diff --git a/ReadMe.md b/ReadMe.md index b3b286e..a1a3f0f 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -35,4 +35,8 @@ cmake --build build --target install # 体积过大 -游戏最后的可执行文件和库是经过压缩的(先`strip`再`upx`),最后结果超出1M很正常。 \ No newline at end of file +游戏最后的可执行文件和库是经过压缩的(先`strip`再`upx`),最后结果超出1M很正常。 + +# 游戏截图 + +![snapshot](./snapshot/snapshot.png) \ No newline at end of file diff --git a/game/HowToPlay.txt b/game/HowToPlay.txt new file mode 100644 index 0000000..f6cad75 --- /dev/null +++ b/game/HowToPlay.txt @@ -0,0 +1,25 @@ +# InfinitShoot + +## 游戏介绍 + +玩家扮演一个枪手,要尽可能地在怪物的围攻中活下来 + +## 游戏玩法 + +左键射击,wasd移动 + +## 游戏内容 + +游戏中的敌人会向你移动,想办法击杀或者躲开它们。 + +游戏中存在三种类型的子弹: + +* 普通子弹:玩家初始的子弹,射速最快,伤害中等,但是没有特殊效果 +* 火焰子弹:射速最慢,但是伤害最高,附加怪物火焰效果 +* 冰冻子弹:射速中等,伤害中等,可以冻住怪物,冰冻期间触碰怪物不会受到伤害 + +特殊效果子弹通过击杀20个敌人后从空投中获得。 + +空投中除了子弹,还有回血的道具,吃完后立刻回血。 + +游戏中的敌人尸体在一定时间后会腐烂,踩在腐烂的尸体上将会极大地减少玩家的速度 \ No newline at end of file diff --git a/game/constants.lua b/game/constants.lua index e26dc39..569033d 100644 --- a/game/constants.lua +++ b/game/constants.lua @@ -13,14 +13,17 @@ _M.SoundName = { _M.TileSize = 32 _M.PlayerInfo = { - velocity = 250, - hp = 100, + velocity = 200, + hp = 50, } +_M.PlayerSlowSpeed = 50 + _M.MonsterInfo = { velocity = 100, hp = 50, damage = 10, } +_M.MonsterDissolveTime = 5 _M.RoleColliBox = { w = 14, h = 32, @@ -51,9 +54,6 @@ _M.MonsetHpBarInfo= { width = _M.TileSize, height = 5, } -_M.GunInfo = { - cooldown = 0.1 -} _M.BulletType = { Normal = 1, @@ -71,20 +71,20 @@ _M.BulletInfo = { [_M.BulletType.Ice] = { damage = 5, velocity = 400, - cooldown = 0.1, + cooldown = 0.2, initNum = 100, }, [_M.BulletType.Fire] = { damage = 7, velocity = 600, - cooldown = 0.1, + cooldown = 0.4, fireDamage = 1, initNum = 100, }, } _M.BulletEffectTime = { - IceTime = 2, + IceTime = 5, FireTime = 2, } _M.RoleState = { diff --git a/game/ecs.lua b/game/ecs.lua index b9cf67c..79d30dc 100644 --- a/game/ecs.lua +++ b/game/ecs.lua @@ -117,7 +117,8 @@ local ComponentType = { Animator = 11, State = 12, Supply = 13, - Image = 14, + SlowTrap = 14, + Image = 15, } _M.ComponentType = ComponentType @@ -430,6 +431,9 @@ function _M.CreateGunComponent(type, bulletNum) o.SetType = function(self, type) self.type = type or constants.BulletType.Normal self.bulletNum = constants.BulletInfo[self.type].initNum + o.cdTimer = timer.CreateTimer(constants.BulletInfo[type].cooldown, -1, function() + o.canShoot = true + end) end o.GetBulletNum = function(self) @@ -521,6 +525,36 @@ function _M.CreateSupplyComponent(type) 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 ---@field rect Rect @@ -575,6 +609,9 @@ function _M.CreateStateComponent(state) local oldHp = roleProp.hp roleProp.hp = roleProp.hp - constants.BulletInfo[constants.BulletType.Fire].fireDamage if oldHp > 0 and roleProp.hp <= 0 then + local slowTrap = _M.CreateSlowTrapComponent() + self:GetParent():SetComponent(slowTrap) + slowTrap:StartDissolve() content.Score = content.Score + 1 helpfuncs.IncKillNum() end @@ -634,7 +671,6 @@ function _M.CreateAnimatorComponent(ani) return _M.CreateComponent(o) end - ---@return Entity ---@param pos Point ---@param damage number @@ -665,7 +701,7 @@ function _M.CreatePlayer(pos) entity:SetComponent(_M.CreateImageComponent(content.Tilesheet, 0, 0)) entity:SetComponent(_M.CreateRolePropComponent(constants.PlayerInfo.hp, constants.PlayerInfo.velocity)) 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.CreateInvincibleComponent(constants.Invincible)) entity:SetComponent(_M.CreateStateComponent()) diff --git a/game/main.lua b/game/main.lua index 5497471..c7fff1c 100644 --- a/game/main.lua +++ b/game/main.lua @@ -66,8 +66,13 @@ end local function updateMonster() ---@param v Entity - for _, v in pairs(content.MonsterList) do - v:Update() + 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() + end end end @@ -92,7 +97,7 @@ local function collisionDeal() local playerPos = content.PlayerEntity:GetComponent(ECS.ComponentType.Transform).position ---@type Rect 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 ---@type Entity local monster = content.MonsterList[km] @@ -162,11 +167,13 @@ local function collisionDeal() hazel.Sound.Play(constants.SoundName.MonsterHurt) if monsterRoleProp:IsDie() then if oldHp > 0 then + ---@type SlowTrapComponent + local slowTrap = ECS.CreateSlowTrapComponent() + monster:SetComponent(slowTrap) + slowTrap:StartDissolve() content.Score = content.Score + 1 helpfunc.IncKillNum() end - table.insert(content.MonsterCorpseList, monster) - content.MonsterList[km] = nil end end end @@ -188,7 +195,7 @@ local function collisionDeal() if type == constants.SupplyType.HpRecover then local index = #content.HpRecoverListAnim + 1 local hpRecoverAnim = animation.CreateAnimation(content.Tilesheet, { - {row = 12, col = 0, time = 0.5}, + {row = 12, col = 1, time = 0.5}, }, function() content.HpRecoverListAnim[index] = nil end) @@ -213,6 +220,33 @@ local function collisionDeal() 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 local function showRestartHint() @@ -243,6 +277,7 @@ local function initGame() content.HpRecoverListAnim = {} content.BulletList = {} content.MonsterList = {} + content.MonsterCorpseList = {} content.SupplyList = {} content.PlayerEntity = ECS.CreatePlayer(hazel.CreatePos(constants.TileSize * 16, constants.TileSize * 13)) content.MonsterBirthNum = constants.MonsterBirthInitNum @@ -346,7 +381,7 @@ local function updateRoles() monster:RemoveComponent(ECS.ComponentType.Direction) monster:RemoveComponent(ECS.ComponentType.AI) monster:RemoveComponent(ECS.ComponentType.HpShow) - monster:RemoveComponent(ECS.ComponentType.ColliBox) + -- monster:RemoveComponent(ECS.ComponentType.ColliBox) monster:RemoveComponent(ECS.ComponentType.State) ---@type ImageComponent local image = monster:GetComponent(ECS.ComponentType.Image) diff --git a/game/resources/tilesheet.png b/game/resources/tilesheet.png index b18a221..0a7a8ee 100644 Binary files a/game/resources/tilesheet.png and b/game/resources/tilesheet.png differ diff --git a/snapshot/snapshot.png b/snapshot/snapshot.png new file mode 100644 index 0000000..57eab67 Binary files /dev/null and b/snapshot/snapshot.png differ