commit b9c23b7cf2768fbe877c3f61db498db338ffda78 Author: UndeadMaelys Date: Fri Dec 31 02:46:21 2021 +0100 Upload of project diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/assets/fangs.png b/assets/fangs.png new file mode 100755 index 0000000..1c921a2 Binary files /dev/null and b/assets/fangs.png differ diff --git a/assets/heart.png b/assets/heart.png new file mode 100755 index 0000000..be10fc1 Binary files /dev/null and b/assets/heart.png differ diff --git a/assets/projectileBlueRocket1.png b/assets/projectileBlueRocket1.png new file mode 100755 index 0000000..b9dd5c3 Binary files /dev/null and b/assets/projectileBlueRocket1.png differ diff --git a/assets/projectileGreenRocket1.png b/assets/projectileGreenRocket1.png new file mode 100755 index 0000000..70d768d Binary files /dev/null and b/assets/projectileGreenRocket1.png differ diff --git a/assets/projectilePiercing1.png b/assets/projectilePiercing1.png new file mode 100755 index 0000000..cf98462 Binary files /dev/null and b/assets/projectilePiercing1.png differ diff --git a/assets/projectilePlasma1.png b/assets/projectilePlasma1.png new file mode 100644 index 0000000..debb455 Binary files /dev/null and b/assets/projectilePlasma1.png differ diff --git a/assets/projectilePlasma2.png b/assets/projectilePlasma2.png new file mode 100644 index 0000000..46a3198 Binary files /dev/null and b/assets/projectilePlasma2.png differ diff --git a/assets/projectilePlasma3.png b/assets/projectilePlasma3.png new file mode 100644 index 0000000..74127a7 Binary files /dev/null and b/assets/projectilePlasma3.png differ diff --git a/assets/projectilePlasma4.png b/assets/projectilePlasma4.png new file mode 100644 index 0000000..cbf96c5 Binary files /dev/null and b/assets/projectilePlasma4.png differ diff --git a/assets/projectilePlasma5.png b/assets/projectilePlasma5.png new file mode 100644 index 0000000..a343029 Binary files /dev/null and b/assets/projectilePlasma5.png differ diff --git a/assets/projectilePlasma6.png b/assets/projectilePlasma6.png new file mode 100644 index 0000000..6514009 Binary files /dev/null and b/assets/projectilePlasma6.png differ diff --git a/assets/projectileRedRocket1.png b/assets/projectileRedRocket1.png new file mode 100755 index 0000000..f1f31a9 Binary files /dev/null and b/assets/projectileRedRocket1.png differ diff --git a/assets/projectileRocket1.png b/assets/projectileRocket1.png new file mode 100755 index 0000000..10b27f6 Binary files /dev/null and b/assets/projectileRocket1.png differ diff --git a/assets/shooter.png b/assets/shooter.png new file mode 100755 index 0000000..d2d91ec Binary files /dev/null and b/assets/shooter.png differ diff --git a/assets/shooter_cannon.png b/assets/shooter_cannon.png new file mode 100755 index 0000000..48b2a1a Binary files /dev/null and b/assets/shooter_cannon.png differ diff --git a/conf.lua b/conf.lua new file mode 100644 index 0000000..0a24a29 --- /dev/null +++ b/conf.lua @@ -0,0 +1,10 @@ +function love.conf(love) + love.title = "ZenLunPera 01" + + -- this is the version of th LOVE framework, not the game! + love.version = "11.3" + + love.window.width = 600 + love.window.height = 600 + love.window.resizable = false +end diff --git a/main.lua b/main.lua new file mode 100644 index 0000000..5219eac --- /dev/null +++ b/main.lua @@ -0,0 +1,109 @@ +function love.load() + require "scripts" + love.graphics.setColor(1,1,1) + love.keyboard.setKeyRepeat(true) + love.graphics.setDefaultFilter("nearest") -- good pixel + window_width = 600 + window_height = 600 + Time = 0 + TimeDone = false + BackgroundColor = {0,0,0} + BackgroundTimer = 0 + BackgroundPeriod = 0.1 + EnemyTimer = 0 + EnemyPeriod = 0.8 + You = Player:New(1/2*window_width,4/5*window_height) + +end + +function love.update(dt) + current_dt = dt + You:Input() + + for _, obj in pairs(List.Simulate) do + obj:Step() + end + + for _, bullet in pairs(List.FriendlyBullet) do + for _, enemy in pairs(List.Enemy) do + if bullet:CollisionWith(enemy) then + if bullet.hits > 0 then + enemy:Damage(bullet.damage) + bullet.hits = bullet.hits - 1 + if bullet.hits <= 0 then + bullet:Kill() + end + end + end + end + end + + for _, bullet in pairs(List.EnemyBullet) do + if bullet:CollisionWith(You) then + if bullet.hits > 0 then + You:Damage(bullet.damage) + bullet.hits = bullet.hits - 1 + if bullet.hits <= 0 then + bullet:Kill() + end + end + end + end + + if TimeDone == false then + Time = Time + dt + EnemyTimer = EnemyTimer + dt + BackgroundTimer = BackgroundTimer + dt + end + + if EnemyTimer >= 0 then --EnemyPeriod then + --EnemyTimer = EnemyTimer - EnemyPeriod + EnemyTimer = -1000000000000 + for i=1, 1 do + local rand = 1 --math.random(10) + if rand == 1 then + local rand_x = math.random(-100,100) + local rand_y = math.random(-100,100) + local x = Shooter:New(1/2*window_width,1/5*window_height) + else + local rand_x = math.random(-10,10) + local rand_y = math.random(-10,10) + local x = Fang:New(window_width/2+rand_x,window_height/2+rand_y) + end + end + end +end + +function love.keypressed(key) + +end + +function love.draw() + love.graphics.setColor(BackgroundColor) + love.graphics.rectangle("fill",0,0,window_width,window_height) + love.graphics.setColor(1,1,1) + You:Draw() + + for _, obj in pairs(List.Simulate) do + obj:Draw() + end + for _, enemy in pairs(List.Enemy) do + if enemy.show_health == true then enemy:DrawHealth() end + end + local width = You.max_health*3 + local height = 20 + love.graphics.setColor(1,1,1) + love.graphics.rectangle("fill",20,10,width, height) + love.graphics.setColor(0,1,0) + love.graphics.rectangle("fill",20+1,10+1,You.health/You.max_health*(width)-2, height-2) + love.graphics.setColor(1,1,1) + + love.graphics.line(0,1/5*window_height,window_height,1/5*window_height) + love.graphics.rectangle("line",0,0,window_width,window_height) + -- overlay + --love.graphics.print(Time, 10, 10) + love.graphics.print(BackgroundTimer, window_width-100, 10) + love.graphics.print(BackgroundPeriod, window_width-100, 20) + love.graphics.print(#List.Simulate, window_width-100, window_height-10) + love.graphics.print(current_dt, 10, window_height-10) +end diff --git a/scripts.lua b/scripts.lua new file mode 100644 index 0000000..3dbe3c8 --- /dev/null +++ b/scripts.lua @@ -0,0 +1,5 @@ +require "scripts/math" +require "scripts/lists" +require "scripts/animations" +require "scripts/attack_patterns" +require "scripts/entity" diff --git a/scripts/animations.lua b/scripts/animations.lua new file mode 100644 index 0000000..2d1b1ea --- /dev/null +++ b/scripts/animations.lua @@ -0,0 +1,142 @@ +Animation = { + projectilePlasma = { + path = "assets/projectilePlasma", + frames = 6, + speed = 0.1, + random = true + }, + projectilePiercing = { + path = "assets/projectilePiercing", + frames = 1, + speed = 1 + }, + projectileRocket = { + path = "assets/projectileRocket", + frames = 1, + speed = 1 + }, + projectileGreen = { + path = "assets/projectileGreenRocket", + frames = 1, + speed = 1 + }, + projectileRed = { + path = "assets/projectileRedRocket", + frames = 1, + speed = 1 + }, + projectileBlue = { + path = "assets/projectileBlueRocket", + frames = 1, + speed = 1 + } +} + + +for _, anim in pairs(Animation) do + anim.imgs = {} + for i = 1, anim.frames do + table.insert(anim.imgs,love.graphics.newImage(anim.path..tostring(i)..".png")) + end +end + +AnimationContainer = {} + +function AnimationContainer:New(anim_data) + local o = {} + o.type = "AnimationContainer" + o.path = anim_data.path + o.frames = anim_data.frames + o.speed = anim_data.speed + o.imgs = anim_data.imgs + + o.subframe = 0 + local random = anim_data.random or false + if random == true then + o.frame = math.random(1,anim_data.frames) + else + o.frame = 1 + end + + table.insert(List.AnimationContainers,o) + o.id = #List.AnimationContainers + + setmetatable(o, self) + self.__index = self + return o +end + +function AnimationContainer:Delete() + for _, animation in pairs(List.AnimationContainers) do + if animation.id > self.id then + animation.id = animation.id - 1 + end + end + table.remove(list,self.id.FriendlyBullet) + self = nil +end + +function AnimationContainer:Set(anim_data) + if anim_data.path == self.path + then + return self + else + return Animation:New(anim_data) + end +end + +-- to manually handle what frame +function AnimationContainer:DrawFrame(frame, x, y, rotate, sx, sy) + if frame > self.frames then + frame = self.frames + end + local x = x or 0 + local y = y or 0 + local sx = sx or 1 + local sy = sy or 1 + love.graphics.draw( + self.imgs[frame], + x - Camera.pos.x, + y - Camera.pos.y, + rotate, + sx, + sy + ) +end + +-- to linearly animate +function AnimationContainer:Animate() + -- try to animate + self.subframe = self.subframe + current_dt + + if self.subframe > self.speed then + self.frame = self.frame + 1 + self.subframe = self.subframe - self.speed + end + + -- cycle + if self.frame >= self.frames+1 then + self.frame = self.frame - self.frames + end +end + +-- to draw the current frame +function AnimationContainer:Draw(x, y, rotate, sx, sy, ox, oy) + local x = x or 0 + local y = y or 0 + local rotate = rotate or 0 + local sx = sx or 1 + local sy = sy or 1 + local ox = ox or self.imgs[self.frame]:getPixelWidth()/2 + local oy = oy or self.imgs[self.frame]:getPixelHeight()/2 + love.graphics.draw( + self.imgs[self.frame], + x, + y, + rotate, + sx, + sy, + ox, + oy + ) +end diff --git a/scripts/attack_patterns.lua b/scripts/attack_patterns.lua new file mode 100644 index 0000000..f9eca8f --- /dev/null +++ b/scripts/attack_patterns.lua @@ -0,0 +1,217 @@ +AttackPattern = {} + +AttackPattern.Wait = function(entity,t,a,b,c) + entity.patternTime = 2 + entity.nextPattern = AttackPattern.PressureWebOfLies + +end + +AttackPattern.PressureWebOfLies = function(entity,t,a,b,c) + if t % 2 == 0 then AttackPattern.FixatedWeb(entity,t,a,b,c) end + + if t % 10 > 7 then AttackPattern.ShotAtPlayerTriple(entity,t,5) end + entity.shotTimer = 0.05 + entity.patternTime = 10 + entity.nextPattern = AttackPattern.Wait +end + +AttackPattern.MortalDrowningBarrage = function(entity,t,a,b,c) + AttackPattern.DrowningBarrage(entity,t,a,b,c) + + if t % 10 > 4 then AttackPattern.ShotAtPlayerDouble(entity,t,a,b,c) end + entity.patternTime = 10 +end + +AttackPattern.FixatedWeb = function(entity,t,a,b,c) + local BulletDataLeft = { + damage = 3, + hits = 1, + moveSpeed = 7, + moveSpeedIncrease = 0.1, + moveHorizontalIncrease = 0.001, + moveSpeedValues = { min = 2, max = 4}, + animation = Animation.projectileGreen, + hostile = true + } + local BulletDataRight = { + damage = 3, + hits = 1, + moveSpeed = 7, + moveSpeedIncrease = 0.1, + moveHorizontalIncrease = -0.001, + moveSpeedValues = { min = 2, max = 4}, + animation = Animation.projectileGreen, + hostile = true + } + local t = t or 0 + if a == nil then + a = -10 + end + gunBullet:New( + entity.pos.x, + entity.pos.y, + math.rad(a *-math.cos( 5 )) + math.rad(90) + math.rad(40) --[[GetAngle( + target_x - entity.pos.x, + target_y - entity.pos.y)]], + BulletDataLeft + ) + gunBullet:New( + entity.pos.x, + entity.pos.y, + math.rad(a *math.cos( 5 )) + math.rad(90) - math.rad(40) --[[GetAngle( + target_x - entity.pos.x, + target_y - entity.pos.y)]], + BulletDataRight + ) + entity.patternTime = 4 + entity.shotTimer = 0.3 + entity.nextPattern = AttackPattern.FixatedWeb +end + +AttackPattern.TwinRays = function(entity,t,a,b,c) + -- variable t is time as always + -- variable a is amplited of the arc + -- variable b is individual bullet (what is calculated) + -- variable c is so it comes back :3 + local t = t or 0 + if a == nil then + a = -10 + end + + local BulletDataRed = { + damage = 3, + hits = 1, + moveSpeed = 3.5, + moveSpeedIncrease = -0.05, + moveSpeedValues = { min = 2, max = 4}, + animation = Animation.projectileRed, + hostile = true + } + local BulletDataBlue = { + damage = 3, + hits = 1, + moveSpeed = 3.5, + moveSpeedIncrease = -0.05, + moveSpeedValues = { min = 2, max = 4}, + animation = Animation.projectileBlue, + hostile = true + } + local target_x = You.pos.x + local target_y = You.pos.y + for i=-1, 1 do + gunBullet:New( + entity.pos.x, + entity.pos.y, + math.rad(a *math.cos(t/5 )) + math.rad(90) + math.rad(45)* i --[[GetAngle( + target_x - entity.pos.x, + target_y - entity.pos.y)]], + BulletDataRed + ) + gunBullet:New( + entity.pos.x, + entity.pos.y, + math.rad(a *-math.cos(t/5 )) + math.rad(90) + math.rad(45)* i --[[GetAngle( + target_x - entity.pos.x, + target_y - entity.pos.y)]], + BulletDataBlue + ) + end + + entity.patternTime = 20 + entity.shotTimer = 0.05 + entity.nextPattern = AttackPattern.Wait +end + +AttackPattern.DrowningBarrage = function(entity,t,a,b,c) + -- variable t is time as always + -- variable a is amplited of the arc + -- variable b is individual bullet (what is calculated) + -- variable c is so it comes back :3 + local t = t or 0 + if a == nil then + a = -10 + end + if b == nil then + b = 0 + end + b = b + a + if c == nil then + c = 100 + end + if math.abs(b) > c then + a = -a + b = c * -math.sign(a) + end + + local BulletData = { + shotCooldown = 0.05, + damage = 3, + hits = 1, + moveSpeed = 3.5, + animation = Animation.projectileRed, + hostile = true + } + local target_x = You.pos.x + local target_y = You.pos.y + entity.shotTimer = BulletData.shotCooldown + gunBullet:New( + entity.pos.x, + entity.pos.y, + math.rad(b *math.cos(t)) + GetAngle( + target_x - entity.pos.x, + target_y - entity.pos.y), + BulletData + ) + entity.patternTime = 2 + entity.nextPattern = AttackPattern.Wait +end + +AttackPattern.ShotAtPlayerDouble = function(entity) + local BulletData = { + shotCooldown = 0.1, + damage = 3, + hits = 1, + moveSpeed = 3, + animation = Animation.projectileGreen, + hostile = true + } + local target_x = You.pos.x + local target_y = You.pos.y + entity.shotTimer = BulletData.shotCooldown + for i=-1, 1 do + if i ~= 0 then + gunBullet:New( + entity.pos.x, + entity.pos.y, + math.rad(-10)*i + GetAngle( + target_x - entity.pos.x, + target_y - entity.pos.y), + BulletData + ) + end + end +end + +AttackPattern.ShotAtPlayerTriple = function(entity,t,a) + local BulletData = { + shotCooldown = 0.1, + damage = 3, + hits = 1, + moveSpeed = a, + animation = Animation.projectileBlue, + hostile = true + } + local target_x = You.pos.x + local target_y = You.pos.y + entity.shotTimer = BulletData.shotCooldown + for i=-1, 1 do + gunBullet:New( + entity.pos.x, + entity.pos.y, + math.rad(-15)*i + GetAngle( + target_x - entity.pos.x, + target_y - entity.pos.y), + BulletData + ) + end +end diff --git a/scripts/entities/bullet.lua b/scripts/entities/bullet.lua new file mode 100644 index 0000000..8884190 --- /dev/null +++ b/scripts/entities/bullet.lua @@ -0,0 +1,84 @@ +gunBullet = Entity:New(x,y) + +function gunBullet:New(x,y,angle,data) + local o = Entity:New(x,y,angle) + + o.target = {} + o.hitbox = 2 + o.draw_scale = 2 + o.angle = angle + + o.hits = data.hits + o.damage = data.damage + o.animation = AnimationContainer:New(data.animation) + o.moveSpeed = data.moveSpeed + o.moveSpeedValues = data.moveSpeedValues or { min = 0, max = 100} + o.moveSpeedIncrease = data.moveSpeedIncrease or 0 + o.moveHorizontalIncrease = data.moveHorizontalIncrease or 0 + o.moveVerticalIncrease = data.moveVerticalIncrease or 0 + o.moveHorizontal = 0 + o.moveVertical = 0 + -- lists + o:AddList(List.Simulate) + + local friendly = data.friendly or false + local hostile = data.hostile or false + + if friendly == true then + o:AddList(List.FriendlyBullet) + end + if hostile == true then + o:AddList(List.EnemyBullet) + end + setmetatable(o, self) + self.__index = self + return o +end + +function gunBullet:Step() + + self.moveSpeed = self.moveSpeed + self.moveSpeedIncrease + self.moveSpeed = math.max(self.moveSpeedValues.min,self.moveSpeed) + self.moveSpeed = math.min(self.moveSpeedValues.max,self.moveSpeed) + + self.moveHorizontal = self.moveHorizontal + self.moveHorizontalIncrease + self.moveVertical = self.moveVertical + self.moveVerticalIncrease + + local move_x = (self.moveSpeed) * math.cos(self.angle) + self.moveHorizontal + local move_y = (self.moveSpeed) * math.sin(self.angle) + self.moveVertical + self.pos.x = self.pos.x + move_x + self.pos.y = self.pos.y + move_y + + self:AngleTowards( + self.pos.x + move_x, + self.pos.y + move_y + ) + + if self.pos.x < 0 or self.pos.x > window_width + or self.pos.y < 0 or self.pos.y > window_height then + self:RemoveList(List.Simulate) + self:RemoveList(List.CollidesEnemies) + end +end + +function gunBullet:Draw() + self.animation:Animate() + love.graphics.line(self.pos.x, self.pos.y, self.pos.x + 10*self.vel.x, self.pos.y + 10*self.vel.y) + self.animation:Draw( + self.pos.x, + self.pos.y, + self.angle+math.rad(90), + self.draw_scale, + self.draw_scale + ) + --[[love.graphics.draw( + self.sprite, + self.pos.x, + self.pos.y, + self.angle+math.rad(90), + self.draw_scale, + self.draw_scale, + self.sprite:getPixelWidth()/2, + self.sprite:getPixelHeight()/2 + )]] +end diff --git a/scripts/entities/enemy/fang.lua b/scripts/entities/enemy/fang.lua new file mode 100644 index 0000000..addf0b3 --- /dev/null +++ b/scripts/entities/enemy/fang.lua @@ -0,0 +1,49 @@ +Fang = Entity:New(x,y) + +function Fang:New(x,y) + local o = Entity:New(x,y) + + o.moveSpeed = 3 + o.hitbox = 10 + o.sprite = love.graphics.newImage("assets/fangs.png") + o.draw_scale = 3 + o.angle = 0 + o.max_health = 3 + o.health = o.max_health + + -- lists + setmetatable(o, self) + self.__index = self + + o:AddList(List.Simulate) + o:AddList(List.Enemy) + return o +end + +function Fang:Step() + if self:CollisionWith(You) then + self.vel.x = 0 + self.vel.y = 0 + You.sprite = nil + else + self:MoveTowards(You.pos.x, You.pos.y, self.moveSpeed) + end + + self.pos.x = self.pos.x + self.vel.x + self.pos.y = self.pos.y + self.vel.y +end + +function Fang:Draw() + self:AngleTowards(You.pos.x, You.pos.y) + love.graphics.line(self.pos.x, self.pos.y, self.pos.x + 10*self.vel.x, self.pos.y + 10*self.vel.y) + love.graphics.draw( + self.sprite, + self.pos.x, + self.pos.y, + self.angle-math.rad(90), + self.draw_scale, + self.draw_scale, + self.sprite:getPixelWidth()/2, + self.sprite:getPixelHeight()/2 + ) +end diff --git a/scripts/entities/enemy/shooter.lua b/scripts/entities/enemy/shooter.lua new file mode 100644 index 0000000..61b0067 --- /dev/null +++ b/scripts/entities/enemy/shooter.lua @@ -0,0 +1,94 @@ +Shooter = Entity:New(x,y) + +function Shooter:New(x,y) + local o = Entity:New(x,y) + + o.moveSpeed = 0 + o.hitbox = 10 + o.sprite = love.graphics.newImage("assets/shooter.png") + o.sprite_cannon = love.graphics.newImage("assets/shooter_cannon.png") + o.draw_scale = 3 + o.angle = 0 + o.max_health = 2000 + o.health = o.max_health + o.show_health = true + o.shotTimer = 1 + -- lists + + setmetatable(o, self) + self.__index = self + + o:AddList(List.Simulate) + o:AddList(List.Enemy) + o:ChangePattern(AttackPattern.DrowningBarrage) + + return o +end + +function Shooter:ChangePattern(pattern) + self.patternTimer = 0 + self.patternTime = 10000 + self.pattern_t = 0 + self.pattern_v1 = nil + self.pattern_v2 = nil + self.pattern_v3 = nil + self.patternActive = pattern + self.nextPattern = nil +end + +function Shooter:Step() + if self.shotTimer > 0 then self.shotTimer = self.shotTimer - current_dt end + if self.shotTimer < 0 then self.shotTimer = 0 end + + --self:AngleTowards(target_x,target_y) + if self.shotTimer <= 0 then + self.pattern_t = self.pattern_t + 1 or 0 + self.patternActive(self,self.pattern_t,self.pattern_v1,self.pattern_v2,self.pattern_v3) + end + + self.patternTimer = self.patternTimer + current_dt + if self.patternTimer >= self.patternTime then + self:ChangePattern(self.nextPattern) + end + + self.pos.x = self.pos.x + self.vel.x + self.pos.y = self.pos.y + self.vel.y +end + +function Shooter:Draw() + love.graphics.draw( + self.sprite, + self.pos.x, + self.pos.y, + 0, --self.angle-math.rad(90), + self.draw_scale, + self.draw_scale, + self.sprite:getPixelWidth()/2, + self.sprite:getPixelHeight()/2 + ) + local bullet_variables = "" + if self.pattern_v1 ~= nil then + bullet_variables = bullet_variables .. " a: " .. self.pattern_v1 .. ", " or "" + end + if self.pattern_v2 ~= nil then + bullet_variables = bullet_variables .. " b: " .. self.pattern_v2 .. ", " or "" + end + if self.pattern_v3 ~= nil then + bullet_variables = bullet_variables .. " c: " .. self.pattern_v3 or "" + end + if self.patternTimer ~= nil then + bullet_variables = bullet_variables .. " TIME: " .. self.patternTimer or "" + end + + love.graphics.print(self.pattern_t .. bullet_variables,self.pos.x,self.pos.y-40) + love.graphics.draw( + self.sprite_cannon, + self.pos.x, + self.pos.y, + self.angle+math.rad(90), + self.draw_scale, + self.draw_scale, + self.sprite:getPixelWidth()/2, + self.sprite:getPixelHeight()/2 + ) +end diff --git a/scripts/entities/player.lua b/scripts/entities/player.lua new file mode 100644 index 0000000..f2709b8 --- /dev/null +++ b/scripts/entities/player.lua @@ -0,0 +1,123 @@ +Player = Entity:New(x,y) + +Player.GunType = { + { + name = "Plasma Machine Gun", + shotCooldown = 0.05, + hits = 1, + damage = 1, + moveSpeed = 8, + animation = Animation.projectilePlasma, + friendly = true + }, + { + name = "Piercing Blaster", + shotCooldown = 0.5, + hits = 3, + damage = 5, + moveSpeed = 5, + animation = Animation.projectilePiercing, + friendly = true + }, + { + name = "Rocket Launcher", + shotCooldown = 1, + hits = 1, + damage = 10, + moveSpeed = 3, + animation = Animation.projectileRocket, + friendly = true + } +} + +function Player:New(x,y) + local o = Entity:New(x,y) + + o.moveSpeed = 3 + o.hitbox = 10 + o.sprite = love.graphics.newImage("assets/heart.png") + o.draw_scale = 3 + + -- gun properties + o.shotTimer = 0 + o.current_gun = 1 + o.gunSwitchTimer = 0 + o.gunSwitchTime = 0.2 + + o.max_health = 100 + o.health = 100 + -- lists + o:AddList(List.Simulate) + + setmetatable(o, self) + self.__index = self + return o +end + +function Player:Input() + if self.sprite ~= nil then + -- gun control + if love.keyboard.isDown("q") then self.gunSwitchTimer = self.gunSwitchTimer - current_dt + elseif love.keyboard.isDown("e") then self.gunSwitchTimer = self.gunSwitchTimer + current_dt + else self.gunSwitchTimer = 0 + end + + if math.abs(self.gunSwitchTimer) > self.gunSwitchTime then + self.current_gun = self.current_gun + math.sign(self.gunSwitchTimer) + self.gunSwitchTimer = 0 + end + + if self.current_gun < 1 then self.current_gun = #self.GunType end + if self.current_gun > #self.GunType then self.current_gun = 1 end + + -- basic movement + if love.keyboard.isDown("a") then self.target.x = self.pos.x - 1 + elseif love.keyboard.isDown("d") then self.target.x = self.pos.x + 1 + else self.target.x = self.pos.x end + + if love.keyboard.isDown("w") then self.target.y = self.pos.y - 1 + elseif love.keyboard.isDown("s") then self.target.y = self.pos.y + 1 + else self.target.y = self.pos.y end + + self:MoveTowards(self.target.x, self.target.y, self.moveSpeed) + + self.pos.x = math.min(math.max(self.pos.x + self.vel.x,self.hitbox),window_width - self.hitbox) + self.pos.y = math.min(math.max(self.pos.y + self.vel.y,self.hitbox),window_height - self.hitbox) + + -- shoot + local x, y = love.mouse.getPosition() + + if self.shotTimer > 0 then self.shotTimer = self.shotTimer - current_dt end + if self.shotTimer < 0 then self.shotTimer = 0 end + + if love.mouse.isDown(1) and self.shotTimer == 0 then + gunBullet:New(self.pos.x,self.pos.y,GetAngle(x - self.pos.x, y - self.pos.y), self.GunType[self.current_gun]) + self.shotTimer = self.GunType[self.current_gun].shotCooldown + end + else + TimeDone = true + end +end + +function Player:Step() + +end + +function Player:Draw() + --love.graphics.circle("line", self.pos.x, self.pos.y, self.hitbox) + + local x, y = love.mouse.getPosition() + love.graphics.circle("line", x, y, self.hitbox/2) + + --love.graphics.line(self.pos.x, self.pos.y, x, y) + love.graphics.print("Current Gun: "..self.GunType[self.current_gun].name, 10, 35) + if self.sprite ~= nil then + love.graphics.draw( + self.sprite, + self.pos.x-self.sprite:getPixelWidth()/2*self.draw_scale, + self.pos.y-self.sprite:getPixelHeight()/2*self.draw_scale, + 0, + self.draw_scale + ) + end +end diff --git a/scripts/entity.lua b/scripts/entity.lua new file mode 100644 index 0000000..9a28f2d --- /dev/null +++ b/scripts/entity.lua @@ -0,0 +1,149 @@ +Entity = {} + +function Entity:New(x,y) + o = {} + o.pos = {x = x, y = y} + o.vel = {x = 0, y = 0} + o.target = {x = 0, y = 0} + o.hitbox = 0 + o.angle = 0 + o.direction = 0 + o.show_health = false + o.id = {} + setmetatable(o, self) + self.__index = self + return o +end + +function Entity:Damage(damage) + self.health = self.health - damage + if self.health <= 0 then + self:Kill() + end +end + +function Entity:DrawHealth() + local width = 400 + local height = 10 + love.graphics.setColor(1,1,1) + love.graphics.rectangle( + "fill", + self.pos.x - width/2, + self.pos.y - height * self.draw_scale, + width, + height + ) + love.graphics.setColor(1,0,0) + love.graphics.rectangle( + "fill", + self.pos.x - width/2+1, + self.pos.y - height * self.draw_scale+1, + self.health/self.max_health*(width-2), + height-2 + ) + love.graphics.setColor(1,1,1) + +end + +function Entity:AddList(list) + table.insert(list,self) + + if list == List.Simulate then + self.id.Simulate = #list + elseif list == List.Enemy then + self.id.Enemy = #list + elseif list == List.EnemyBullet then + self.id.EnemyBullet = #list + elseif list == List.FriendlyBullet then + self.id.FriendlyBullet = #list + end +end + +function Entity:CollisionWith(obj) + if math.sqrt((obj.pos.x-self.pos.x)^2 + (obj.pos.y-self.pos.y)^2) < obj.hitbox + self.hitbox then + return true + else + return false + end +end + +function Entity:RemoveList(list) + if list == List.Simulate then + for _, e in pairs(list) do + if e.id.Simulate > self.id.Simulate then + e.id.Simulate = e.id.Simulate - 1 + end + end + table.remove(list,self.id.Simulate) + elseif list == List.Enemy then + for _, e in pairs(list) do + if e.id.Enemy > self.id.Enemy then + e.id.Enemy = e.id.Enemy - 1 + end + end + table.remove(list,self.id.Enemy) + elseif list == List.EnemyBullet then + for _, e in pairs(list) do + if e.id.EnemyBullet > self.id.EnemyBullet then + e.id.EnemyBullet = e.id.EnemyBullet - 1 + end + end + table.remove(list,self.id.EnemyBullet) + elseif list == List.FriendlyBullet then + for _, e in pairs(list) do + if e.id.FriendlyBullet > self.id.FriendlyBullet then + e.id.FriendlyBullet = e.id.FriendlyBullet - 1 + end + end + table.remove(list,self.id.FriendlyBullet) + end +end + +function Entity:AngleTowards(x,y) + target_x = x - self.pos.x + target_y = y - self.pos.y + + self.angle = GetAngle(target_x,target_y) +end + +function Entity:Kill() + if self.id.Simulate ~= nil then + self:RemoveList(List.Simulate) + end + if self.id.Enemy ~= nil then + self:RemoveList(List.Enemy) + end + if self.id.EnemyBullet ~= nil then + self:RemoveList(List.EnemyBullet) + end + if self.id.FriendlyBullet ~= nil then + self:RemoveList(List.FriendlyBullet) + end + + self = nil +end + +function Entity:MoveTowards(x,y,speed) + target_x = x - self.pos.x + target_y = y - self.pos.y + + local angle = GetAngle(target_x,target_y) + + if speed ~= 0 then + if target_x ~= 0 then + self.vel.x = speed * math.cos(angle) + else + self.vel.x = 0 + end + if target_y ~= 0 then + self.vel.y = speed * math.sin(angle) + else + self.vel.y = 0 + end + end +end + +require "scripts/entities/player" +require "scripts/entities/enemy/fang" +require "scripts/entities/enemy/shooter" +require "scripts/entities/bullet" diff --git a/scripts/lists.lua b/scripts/lists.lua new file mode 100644 index 0000000..4be5e5e --- /dev/null +++ b/scripts/lists.lua @@ -0,0 +1,12 @@ +List = {} + +-- list to simulate things (draw, step, move) +List.Simulate = {} + +-- collide lists +List.Enemy = {} +List.EnemyBullet = {} +List.FriendlyBullet = {} + + +List.AnimationContainers = {} diff --git a/scripts/math.lua b/scripts/math.lua new file mode 100644 index 0000000..380c045 --- /dev/null +++ b/scripts/math.lua @@ -0,0 +1,17 @@ +function GetAngle(x,y) + local reduce = 0 + if x < 0 then + reduce = math.rad(180) + end + return math.atan(y/x) - reduce +end + +function math.sign(x) + if x > 0 then + return 1 + elseif x < 0 then + return -1 + else + return 0 + end +end