diff --git a/Games/Medieval RPG/missile-command-master/README.md b/Games/Medieval RPG/missile-command-master/README.md new file mode 100644 index 0000000000..f61f224fab --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/README.md @@ -0,0 +1,37 @@ + +## Controls + +* `up` `down` `left` `right` arrows move cursor +* `spacebar` fires bomb + +## Build From Source + +1. Download and install LÖVE for OS X, Windows or Linux. http://love2d.org +2. Clone this repo and [load the game](https://love2d.org/wiki/Getting_Started#Running_Games). + +## Video +* https://www.youtube.com/watch?v=9OOp6z5Ykw8 + + + +# **Missile-command** + +<br> + +## **Description 📃** +<!-- add your game description here --> +- A 2d game of shooting + + +<br> + +## **Screenshots 📸** + +<br> +<!-- add your screenshots like this --> +<img src="./missile.png" alt="Image Description"> +<br> + + + + diff --git a/Games/Medieval RPG/missile-command-master/audio.lua b/Games/Medieval RPG/missile-command-master/audio.lua new file mode 100644 index 0000000000..541925731c --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/audio.lua @@ -0,0 +1,50 @@ +audio = class('audio') + +function audio:initialize() + + self.boom = love.audio.newSource('audio/missile_explode.ogg','static') + self.launch = love.audio.newSource('audio/launch_bomb.ogg','static') + self.start = love.audio.newSource('audio/start_level.ogg','static') + self.over = love.audio.newSource('audio/game_over.ogg','static') + self.noammo = love.audio.newSource('audio/no_ammo.ogg','static') + +end + +function audio:play(sound) + + if sound == 'boom' then + + self.boom:stop() + self.boom:play() + + elseif sound == 'launch' then + + if not self.boom:isPlaying() then + + self.launch:stop() + self.launch:play() + + end + + elseif sound == 'start_level' then + + self.start:stop() + self.start:play() + + elseif sound == 'game_over' then + + self.over:stop() + self.over:play() + + elseif sound == 'no_ammo' then + + if not self.boom:isPlaying() then + + self.noammo:stop() + self.noammo:play() + + end + + end + +end \ No newline at end of file diff --git a/Games/Medieval RPG/missile-command-master/audio/game_over.ogg b/Games/Medieval RPG/missile-command-master/audio/game_over.ogg new file mode 100644 index 0000000000..7620ff8c28 Binary files /dev/null and b/Games/Medieval RPG/missile-command-master/audio/game_over.ogg differ diff --git a/Games/Medieval RPG/missile-command-master/audio/launch_bomb.ogg b/Games/Medieval RPG/missile-command-master/audio/launch_bomb.ogg new file mode 100644 index 0000000000..8ccc03668f Binary files /dev/null and b/Games/Medieval RPG/missile-command-master/audio/launch_bomb.ogg differ diff --git a/Games/Medieval RPG/missile-command-master/audio/missile_explode.ogg b/Games/Medieval RPG/missile-command-master/audio/missile_explode.ogg new file mode 100644 index 0000000000..76915f279c Binary files /dev/null and b/Games/Medieval RPG/missile-command-master/audio/missile_explode.ogg differ diff --git a/Games/Medieval RPG/missile-command-master/audio/no_ammo.ogg b/Games/Medieval RPG/missile-command-master/audio/no_ammo.ogg new file mode 100644 index 0000000000..b13b792256 Binary files /dev/null and b/Games/Medieval RPG/missile-command-master/audio/no_ammo.ogg differ diff --git a/Games/Medieval RPG/missile-command-master/audio/start_level.ogg b/Games/Medieval RPG/missile-command-master/audio/start_level.ogg new file mode 100644 index 0000000000..283cdd59cc Binary files /dev/null and b/Games/Medieval RPG/missile-command-master/audio/start_level.ogg differ diff --git a/Games/Medieval RPG/missile-command-master/bomb.lua b/Games/Medieval RPG/missile-command-master/bomb.lua new file mode 100644 index 0000000000..e7766f9517 --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/bomb.lua @@ -0,0 +1,28 @@ +bomb = class('bomb') + +function bomb:initialize(world,x,y) + + self.xtarget = x + self.ytarget = y + + self.body = love.physics.newBody(world,400,500,"kinematic") + local vx = x - game.bombtower.x + local vy = y - game.bombtower.y + self.body:setBullet(true) + self.body:setLinearVelocity(vx,vy) + + self.shape = love.physics.newRectangleShape(x,y,8,4) + local x1, y1, x2, y2 = self.shape:computeAABB(0,0,0) + self.width = x2 - x1 + self.height = y2 - y1 + + self.fixture = love.physics.newFixture(self.body, self.shape, 1.0) + +end + +function bomb:draw() + + love.graphics.setColor(math.random(0,255),math.random(0,255),math.random(0,255)) + love.graphics.rectangle('fill',self.body:getX(),self.body:getY(),self.width,self.height) + +end \ No newline at end of file diff --git a/Games/Medieval RPG/missile-command-master/build.sh b/Games/Medieval RPG/missile-command-master/build.sh new file mode 100644 index 0000000000..bfbb3fd9cd --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/build.sh @@ -0,0 +1,3 @@ +#!/bin/sh +rm missile-command.love +zip -r missile-command.love * diff --git a/Games/Medieval RPG/missile-command-master/city.lua b/Games/Medieval RPG/missile-command-master/city.lua new file mode 100644 index 0000000000..9b49616827 --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/city.lua @@ -0,0 +1,21 @@ +city = class('city') + +function city:initialize(x,y) + + self.x = x + self.y = y + self.width = 35 + self.height = 25 + + self.body = love.physics.newBody(world,x,y,'dynamic') + self.shape = love.physics.newRectangleShape(x,y,self.width,self.height) + self.fixture = love.physics.newFixture(self.body, self.shape, 0.1) + +end + +function city:draw(color) + + love.graphics.setColor(color) + love.graphics.polygon('fill',self.shape:getPoints()) + +end \ No newline at end of file diff --git a/Games/Medieval RPG/missile-command-master/conf.lua b/Games/Medieval RPG/missile-command-master/conf.lua new file mode 100644 index 0000000000..b38001c840 --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/conf.lua @@ -0,0 +1,4 @@ +function love.conf(t) + t.title = 'Missile Command' + t.author = 'Chad Paulson' +end diff --git a/Games/Medieval RPG/missile-command-master/cron.lua b/Games/Medieval RPG/missile-command-master/cron.lua new file mode 100644 index 0000000000..8a93a8159d --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/cron.lua @@ -0,0 +1,87 @@ +----------------------------------------------------------------------------------------------------------------------- +-- cron.lua - v1.0 (2011-04) +-- Enrique García Cota - enrique.garcia.cota [AT] gmail [DOT] com +-- time-related functions for Lua. +-- inspired by Javascript's setTimeout and setInterval +----------------------------------------------------------------------------------------------------------------------- + + +local function isCallable(callback) + local tc = type(callback) + if tc == 'function' then return true end + if tc == 'table' then + local mt = getmetatable(callback) + return type(mt) == 'table' and type(mt.__call) == 'function' + end + return false +end + +local function checkTimeAndCallback(time, callback) + assert(type(time) == "number" and time > 0, "time must be a positive number") + assert(isCallable(callback), "callback must be a function") +end + +local entries = setmetatable({}, {__mode = "k"}) + +local function newEntry(time, callback, update, ...) + local entry = { + time = time, + callback = callback, + args = {...}, + running = 0, + update = update + } + entries[entry] = entry + return entry +end + +local function updateTimedEntry(self, dt) -- returns true if expired + self.running = self.running + dt + if self.running >= self.time then + self.callback(unpack(self.args)) + return true + end +end + +local function updatePeriodicEntry(self, dt) + self.running = self.running + dt + + while self.running >= self.time do + self.callback(unpack(self.args)) + self.running = self.running - self.time + end +end + +local cron = {} + +function cron.reset() + entries = {} +end + +function cron.cancel(id) + entries[id] = nil +end + +function cron.after(time, callback, ...) + checkTimeAndCallback(time, callback) + return newEntry(time, callback, updateTimedEntry, ...) +end + +function cron.every(time, callback, ...) + checkTimeAndCallback(time, callback) + return newEntry(time, callback, updatePeriodicEntry, ...) +end + +function cron.update(dt) + assert(type(dt) == "number" and dt > 0, "dt must be a positive number") + + local expired = {} + + for _, entry in pairs(entries) do + if entry:update(dt, runningTime) then table.insert(expired,entry) end + end + + for i=1, #expired do entries[expired[i]] = nil end +end + +return cron diff --git a/Games/Medieval RPG/missile-command-master/cursor.lua b/Games/Medieval RPG/missile-command-master/cursor.lua new file mode 100644 index 0000000000..7827236d70 --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/cursor.lua @@ -0,0 +1,17 @@ +cursor = class('cursor') + +function cursor:initialize(x,y) + + self.x = x + self.y = y + self.width = 36 + self.height = 8 + +end + +function cursor:draw() + + love.graphics.setColor(255,255,255) + love.graphics.rectangle('fill',self.x - (self.width / 2),self.y,self.width,self.height) + +end \ No newline at end of file diff --git a/Games/Medieval RPG/missile-command-master/explosion.lua b/Games/Medieval RPG/missile-command-master/explosion.lua new file mode 100644 index 0000000000..64a88afaee --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/explosion.lua @@ -0,0 +1,50 @@ +explosion = class('explosion') + +function explosion:initialize(world,x,y) + + self.stage = 1 + self.x = x + self.y = y + + self.body = love.physics.newBody(world,self.x,self.y,'dynamic') + self.shape = love.physics.newPolygonShape(self:plotExplosion(self.stage)) + + self.fixture = love.physics.newFixture(self.body, self.shape, 1.0) + +end + +function explosion:update() + + if self.stage == 75 then + self.body:destroy() + return false + elseif self.stage < 75 then + self.stage = self.stage + 1 + self.shape = love.physics.newPolygonShape(self:plotExplosion(self.stage)) + return true + end + +end + +function explosion:draw() + + love.graphics.setColor(math.random(0,255),math.random(0,255),math.random(0,255)) + love.graphics.polygon('fill', self.shape:getPoints()) + +end + +function explosion:plotExplosion(stage) + + x = 0 + y = 0 + if stage < 15 then + padding = stage * 2 + elseif stage > 15 and stage < 50 then + padding = 45 + elseif stage >= 50 then + padding = 80 - stage + end + + return self.x,self.y - padding, self.x + padding, self.y, self.x, self.y + padding, self.x - padding, self.y + +end \ No newline at end of file diff --git a/Games/Medieval RPG/missile-command-master/game.lua b/Games/Medieval RPG/missile-command-master/game.lua new file mode 100644 index 0000000000..803571b52f --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/game.lua @@ -0,0 +1,305 @@ +game = class('game') + +function game:initialize() + + self.screen = {} + self.screen.width = 800 + self.screen.height = 600 + self.audio = audio:new() + self.missiles = {} + self.bombs = {} + self.explosions = {} + self.cursor = cursor:new(350,350) + self.bombtower = {} + self.bombtower.x = 400 + self.bombtower.y = 500 + self.current_level = 1 + self.level = level:new(self.current_level) + self.score = score:new() + self.cities = self:buildCities() + self.audio:play('start_level') + self.game_over = false + + cron = require 'cron' + cron.every(self.level.missile_interval,launchMissiles) + + imgfont = love.graphics.newImageFont('gfx/imgfont2.png'," ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") + love.graphics.setFont(imgfont) + +end + +function game:update(dt) + + if self.level.num_missiles == self.level.launched_missiles and table.getn(self.missiles) == 0 and self.level.num_missiles > 0 and not self.game_over then + + self.score:add(self.level.num_bombs * 5) -- extra bomb bonus + + if table.getn(self.cities) > 0 and self.current_level < 9 then + + self:advanceLevel() + + else + + self:gameOver() + + end + + end + + cron.update(dt) + + for k,e in pairs(self.explosions) do + + -- check for exploded missiles + for k,missile in pairs(self.missiles) do + if e.shape:testPoint(0,0,0,missile.body:getX(),missile.body:getY()) then + local exp = explosion:new(world,missile.body:getX(),missile.body:getY() - 15) + table.insert(self.explosions,exp) + + missile.body:destroy() + self.audio:play('boom') + table.remove(self.missiles,k) + self.level.destroyed_missiles = self.level.destroyed_missiles + 1 + self.score:add(25) + end + end + + if not e:update() then + table.remove(self.explosions,k) + end + + end + + + for ck,city in pairs(self.cities) do + + for k,missile in pairs(self.missiles) do + + if city.shape:testPoint(0,0,0,missile.body:getX(),missile.body:getY()) then + local e = explosion:new(world,missile.body:getX(),missile.body:getY() - 10) + table.insert(self.explosions,e) + + missile.body:destroy() + self.audio:play('boom') + table.remove(self.missiles,k) + self.level.destroyed_missiles = self.level.destroyed_missiles + 1 + + city.body:destroy() + table.remove(self.cities,ck) + break + end + + end + + end + + for k,missile in pairs(self.missiles) do + + if missile.body:getY() > 525 then + missile.body:destroy() + table.remove(self.missiles,k) + self.level.destroyed_missiles = self.level.destroyed_missiles + 1 + end + + end + + for k,b in pairs(self.bombs) do + + if self:testCollision(b.body,b.xtarget,b.ytarget) then + + local e = explosion:new(world,b.xtarget,b.ytarget) + table.insert(self.explosions,e) + + b.body:destroy() + table.remove(self.bombs,k) + + end + + end + + if love.keyboard.isDown('up') and self.cursor.y > 0 then + self.cursor.y = self.cursor.y - 8 + elseif self.cursor.y < 0 then + self.cursor.y = 0 + end + + if love.keyboard.isDown('right') and self.cursor.x < self.screen.width then + self.cursor.x = self.cursor.x + 8 + elseif self.cursor.x > self.screen.width then + self.cursor.x = self.screen.width + end + + if love.keyboard.isDown('down') and self.cursor.y < (self.bombtower.y - self.cursor.height) then + self.cursor.y = self.cursor.y + self.cursor.height + elseif self.cursor.y > self.bombtower.y then + self.cursor.y = self.bombtower.y + end + + if love.keyboard.isDown('left') and self.cursor.x > 0 then + self.cursor.x = self.cursor.x - 8 + elseif self.cursor.x < 0 then + self.cursor.x = 0 + end + +end + +function game:draw() + + love.graphics.setBackgroundColor(self.level.background_color) + + for k,b in pairs(self.bombs) do + + b:draw() + + end + + for k,m in pairs(self.missiles) do + + m:draw(self.level.missile_tail_color,self.level.missile_color) + + end + + for k,c in pairs(self.cities) do + + c:draw(self.level.city_color) + + end + + for k,e in pairs(self.explosions) do + + e:draw() + + end + + self.cursor:draw() + + self.score:draw() + + self:drawInanimateObjects() + +end + +function game:launchMissile() + + if self.level.num_missiles > self.level.launched_missiles and not self.audio.start:isPlaying() then + + local xcoords = {112,115,110,120,105,700,176,247,554,625,696,400,683} + local index = math.random(1,13) + local xcoord = xcoords[index] + local ycoord = 35 + local m = missile:new(world,xcoord,ycoord,self.level.missile_speed) + + table.insert(self.missiles,m) + self.level.launched_missiles = self.level.launched_missiles + 1 + + end + +end + +function game:shoot() + + if self.level.num_bombs > 0 then + + local b = bomb:new(world,self.cursor.x,self.cursor.y) + table.insert(self.bombs,b) + self.level.num_bombs = self.level.num_bombs - 1 + self.audio:play('launch') + + else + + self.audio:play('no_ammo') + + end + +end + +function game:testCollision(body,x,y) + + local vx1 = body:getX() - game.bombtower.x + local vy1 = body:getY() - game.bombtower.y + + local vx2 = x - game.bombtower.x + local vy2 = y - game.bombtower.y + + if vx1 - vx2 < 4 and vy1 - vy2 < 4 then + return true + end + + return false + +end + +function game:gameOver() + + self.game_over = true + self.audio:play('game_over') + +end + +function game:startOver() + + self.audio:play('start_level') + self.current_level = 1 + self.cities = self:buildCities() + self.game_over = false + self.score.total = 0 + self.level = level:new(self.current_level) + cron.reset() + cron.every(self.level.missile_interval,launchMissiles) + +end + +function game:advanceLevel() + + if self.current_level < 9 then + + self.audio:play('start_level') + self.current_level = self.current_level + 1 + self.level = level:new(self.current_level) + cron.reset() + cron.every(self.level.missile_interval,launchMissiles) + + else + + self:gameOver() + + end + +end + +function game:drawInanimateObjects() + + -- ground + love.graphics.setColor(self.level.ground_color) + love.graphics.rectangle('fill',0 ,525,self.screen.width,75) + love.graphics.rectangle('fill',0,500,50,25) + love.graphics.rectangle('fill',750,500,50,25) + love.graphics.rectangle('fill',300,515,200,10) + love.graphics.rectangle('fill',325,505,150,10) + love.graphics.rectangle('fill',350,495,100,10) + + -- bomb + if self.level.num_bombs > 0 then + + love.graphics.setColor(math.random(0,255),math.random(0,255),math.random(0,255)) + love.graphics.rectangle('fill',self.bombtower.x,self.bombtower.y - 8,8,4) + + end + +end + +function game:buildCities() + + return {city:new(105,513),city:new(176,513),city:new(247,513),city:new(554,513),city:new(625,513),city:new(696,513)} + +end + +function launchMissiles() + + local num_missiles = math.random(1,game.level.max_concurrent_missiles) + + for i=1, num_missiles do + game:launchMissile() + end + +end \ No newline at end of file diff --git a/Games/Medieval RPG/missile-command-master/gamedebug.lua b/Games/Medieval RPG/missile-command-master/gamedebug.lua new file mode 100644 index 0000000000..b9120fd901 --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/gamedebug.lua @@ -0,0 +1,24 @@ +gamedebug = class('gamedebug') + +function gamedebug:initialize(isEnabled) + + self.isEnabled = isEnabled + +end + +function gamedebug:draw() + + if self.isEnabled then + + love.graphics.setColor(255,255,255) + love.graphics.print('x: ' .. game.cursor.x .. ' y: ' .. game.cursor.y,8,8) + love.graphics.print(love.timer.getFPS() .. ' fps',8,20) + love.graphics.print('level: ' .. game.current_level,8,36) + love.graphics.print('score: ' .. game.score.total,8,46) + love.graphics.print('bombs: ' .. game.level.num_bombs,8,62) + love.graphics.print('cities: ' .. table.getn(game.cities),8,76) + love.graphics.print('missiles left: ' .. game.level.num_missiles - game.level.launched_missiles,8,86) + + end + +end \ No newline at end of file diff --git a/Games/Medieval RPG/missile-command-master/gfx/imgfont.png b/Games/Medieval RPG/missile-command-master/gfx/imgfont.png new file mode 100644 index 0000000000..6ce8cc760b Binary files /dev/null and b/Games/Medieval RPG/missile-command-master/gfx/imgfont.png differ diff --git a/Games/Medieval RPG/missile-command-master/gfx/imgfont2.png b/Games/Medieval RPG/missile-command-master/gfx/imgfont2.png new file mode 100644 index 0000000000..6afb513840 Binary files /dev/null and b/Games/Medieval RPG/missile-command-master/gfx/imgfont2.png differ diff --git a/Games/Medieval RPG/missile-command-master/level.lua b/Games/Medieval RPG/missile-command-master/level.lua new file mode 100644 index 0000000000..d463f6e8a7 --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/level.lua @@ -0,0 +1,140 @@ +level = class('level') + +function level:initialize(level_num) + + self.missile_color = {} + self.missile_tail_color = {} + self.background_color = {} + self.city_color = {} + self.ground_color = {} + + self.num_bombs = 0 + self.num_missiles = 0 + self.destroyed_missiles = 0 + self.launched_missiles = 0 + self.destroyed_cities = 0 + self.missile_speed = 0 + self.max_concurrent_missiles = 0 + + self:loadLevel(level_num) + +end + +function level:loadLevel(level_num) + + self.destroyed_missiles = 0 + self.launched_missiles = 0 + self.num_bombs = 30 + self.destroyed_cities = 0 + + if level_num == 1 then + + self.missile_color = {255,255,255} + self.missile_tail_color = {255,0,0} + self.background_color = {0,0,0,1} + self.city_color = {0,0,255,1} + self.ground_color = {230,158,00,1} + self.num_missiles = 12 + self.missile_speed = 1 + self.missile_interval = 5 + self.max_concurrent_missiles = 2 + + elseif level_num == 2 then + + self.missile_color = {125,48,173} + self.missile_tail_color = {255,255,255} + self.background_color = {147,0,0,1} + self.city_color = {0,255,0,1} + self.ground_color = {125,0,173,1} + self.num_missiles = 14 + self.missile_speed = 2 + self.missile_interval = 4 + self.max_concurrent_missiles = 3 + + elseif level_num == 3 then + + self.missile_color = {255,255,255} + self.missile_tail_color = {154,252,154} + self.background_color = {0,0,0} + self.city_color = {0,30,255,1} + self.ground_color = {193,209,0,1} + self.num_missiles = 16 + self.missile_speed = 2 + self.missile_interval = 4 + self.max_concurrent_missiles = 3 + + elseif level_num == 4 then + + self.missile_color = {255,255,255} + self.missile_tail_color = {0,0,0} + self.background_color = {212,211,0,1} + self.city_color = {255,0,0,1} + self.ground_color = {0,102,50,1} + self.num_missiles = 18 + self.missile_speed = 3 + self.missile_interval = 4 + self.max_concurrent_missiles = 4 + + elseif level_num == 5 then + + self.missile_color = {0,0,0} + self.missile_tail_color = {255,255,255} + self.background_color = {50,132,0,1} + self.city_color = {0,162,226,1} + self.ground_color = {0,0,0,1} + self.num_missiles = 20 + self.missile_speed = 3 + self.missile_interval = 3 + self.max_concurrent_missiles = 4 + + elseif level_num == 6 then + + self.missile_color = {255,255,255} + self.missile_tail_color = {255,5,5} + self.background_color = {78,0,181,1} + self.city_color = {213,211,0,1} + self.ground_color = {0,189,93,1} + self.num_missiles = 22 + self.missile_speed = 4 + self.missile_interval = 3 + self.max_concurrent_missiles = 5 + + elseif level_num == 7 then + + self.missile_color = {255,255,255} + self.missile_tail_color = {0,32,53} + self.background_color = {165,53,0,1} + self.city_color = {0,89,193,1} + self.ground_color = {0,0,0,1} + self.num_missiles = 24 + self.missile_speed = 4 + self.missile_interval = 3 + self.max_concurrent_missiles = 6 + + elseif level_num == 8 then + + self.missile_color = {255,0,0} + self.missile_tail_color = {235,235,235} + self.background_color = {0,0,0,1} + self.city_color = {255,255,255,1} + self.ground_color = {0,191,208,1} + self.num_missiles = 26 + self.missile_speed = 4 + self.missile_interval = 2 + self.max_concurrent_missiles = 7 + + elseif level_num == 9 then + + self.missile_color = {255,255,255} + self.missile_tail_color = {246,0,255} + self.background_color = {0,0,0,1} + self.city_color = {82,251,59,1} + self.ground_color = {181,0,170,1} + self.num_missiles = 28 + self.missile_speed = 5 + self.missile_interval = 2 + self.max_concurrent_missiles = 8 + + end + +end \ No newline at end of file diff --git a/Games/Medieval RPG/missile-command-master/main.lua b/Games/Medieval RPG/missile-command-master/main.lua new file mode 100644 index 0000000000..0b55d65a99 --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/main.lua @@ -0,0 +1,53 @@ +require 'middleclass' +require 'game' +require 'level' +require 'gamedebug' +require 'audio' +require 'score' +require 'cursor' +require 'city' +require 'missile' +require 'explosion' +require 'bomb' + +function love.load() + + world = love.physics.newWorld(-800,-600,800,600,0,1.1) + game = game:new() + + debug = gamedebug:new(false) -- set to true to enable debug display + love.mouse.setVisible(false) + +end + +function love.update(dt) + + world:update(dt) + + game:update(dt) + +end + +function love.keypressed(key) + + if key == 'escape' then + love.event.push('q') + end + + if key == 'space' then + game:shoot() + end + + if game.game_over and not game.audio.over:isPlaying() then + game:startOver() + end + +end + +function love.draw() + + game:draw() + + debug:draw() + +end diff --git a/Games/Medieval RPG/missile-command-master/middleclass.lua b/Games/Medieval RPG/missile-command-master/middleclass.lua new file mode 100644 index 0000000000..09a2ad14d0 --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/middleclass.lua @@ -0,0 +1,120 @@ +----------------------------------------------------------------------------------------------------------------------- +-- middleclass.lua - v1.4 (2011-03) +-- Enrique García Cota - enrique.garcia.cota [AT] gmail [DOT] com +-- Based on YaciCode, from Julien Patte and LuaObject, from Sébastien Rocca-Serra +----------------------------------------------------------------------------------------------------------------------- + +local _nilf = function() end -- empty function + +local _classes = setmetatable({}, {__mode = "k"}) -- keeps track of all the tables that are classes + +Object = { name = "Object", __mixins = {} } + +Object.__classDict = { + initialize = _nilf, destroy = _nilf, subclassed = _nilf, + __tostring = function(instance) return ("instance of ".. instance.class.name) end, -- root of __tostring method, + __metamethods = { '__add', '__call', '__concat', '__div', '__le', '__lt', + '__mod', '__mul', '__pow', '__sub', '__tostring', '__unm' + } +} +Object.__classDict.__index = Object.__classDict -- instances of Object need this + +setmetatable(Object, { + __index = Object.__classDict, -- look up methods in the classDict + __newindex = Object.__classDict, -- any new Object methods will be defined in classDict + __call = Object.new, -- allows instantiation via Object() + __tostring = function() return "class Object" end -- allows tostring(obj) +}) + +_classes[Object] = true -- register Object on the list of classes. + +-- creates the instance based of the class, but doesn't initialize it +function Object.allocate(theClass) + assert(_classes[theClass], "Use Class:allocate instead of Class.allocate") + return setmetatable({ class = theClass }, theClass.__classDict) +end + +-- both creates and initializes an instance +function Object.new(theClass, ...) + local instance = theClass:allocate() + instance:initialize(...) + return instance +end + +-- creates a subclass +function Object.subclass(theClass, name) + assert(_classes[theClass], "Use Class:subclass instead of Class.subclass") + assert( type(name)=="string", "You must provide a name(string) for your class") + + local theSubClass = { name = name, superclass = theClass, __classDict = {}, __mixins={} } + + local dict = theSubClass.__classDict -- classDict contains all the [meta]methods of the class + dict.__index = dict -- It "points to itself" so instances can use it as a metatable. + local superDict = theClass.__classDict -- The superclass' classDict + + setmetatable(dict, superDict) -- when a method isn't found on classDict, 'escalate upwards'. + + setmetatable(theSubClass, { + __index = dict, -- look for stuff on the dict + __newindex = function(_, methodName, method) -- ensure that __index isn't modified by mistake + assert(methodName ~= '__index', "Can't modify __index. Include middleclass-extras.Indexable and use 'index' instead") + rawset(dict, methodName , method) + end, + __tostring = function() return ("class ".. name) end, -- allows tostring(MyClass) + __call = function(_, ...) return theSubClass:new(...) end -- allows MyClass(...) instead of MyClass:new(...) + }) + + for _,mmName in ipairs(theClass.__metamethods) do -- Creates the initial metamethods + dict[mmName]= function(...) -- by default, they just 'look up' for an implememtation + local method = superDict[mmName] -- and if none found, they throw an error + assert( type(method)=='function', tostring(theSubClass) .. " doesn't implement metamethod '" .. mmName .. "'" ) + return method(...) + end + end + + theSubClass.initialize = function(instance,...) theClass.initialize(instance, ...) end + _classes[theSubClass]= true -- registers the new class on the list of _classes + theClass:subclassed(theSubClass) -- hook method. By default it does nothing + + return theSubClass +end + +-- Mixin extension function - simulates very basically ruby's include. Receives a table table, probably with functions. +-- Its contents are copied to theClass, with one exception: the included() method will be called instead of copied +function Object.include(theClass, mixin, ... ) + assert(_classes[theClass], "Use class:include instead of class.include") + assert(type(mixin)=='table', "mixin must be a table") + for methodName,method in pairs(mixin) do + if methodName ~="included" then theClass[methodName] = method end + end + if type(mixin.included)=="function" then mixin:included(theClass, ... ) end + theClass.__mixins[mixin] = mixin + return theClass +end + +-- Returns true if aClass is a subclass of other, false otherwise +function subclassOf(other, aClass) + if not _classes[aClass] or not _classes[other] then return false end + if aClass.superclass==nil then return false end -- aClass is Object, or a non-class + return aClass.superclass == other or subclassOf(other, aClass.superclass) +end + +-- Returns true if obj is an instance of aClass (or one of its subclasses) false otherwise +function instanceOf(aClass, obj) + if not _classes[aClass] or type(obj)~='table' or not _classes[obj.class] then return false end + if obj.class==aClass then return true end + return subclassOf(aClass, obj.class) +end + +-- Returns true if the mixin has already been included on a class (or a superclass) +function includes(mixin, aClass) + if not _classes[aClass] then return false end + if aClass.__mixins[mixin]==mixin then return true end + return includes(mixin, aClass.superclass) +end + +-- Creates a new class named 'name'. Uses Object if no baseClass is specified. +function class(name, baseClass, ...) + baseClass = baseClass or Object + return baseClass:subclass(name, ...) +end \ No newline at end of file diff --git a/Games/Medieval RPG/missile-command-master/missile-command.love b/Games/Medieval RPG/missile-command-master/missile-command.love new file mode 100644 index 0000000000..0c73b9f236 Binary files /dev/null and b/Games/Medieval RPG/missile-command-master/missile-command.love differ diff --git a/Games/Medieval RPG/missile-command-master/missile.lua b/Games/Medieval RPG/missile-command-master/missile.lua new file mode 100644 index 0000000000..709a848441 --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/missile.lua @@ -0,0 +1,40 @@ +missile = class('missile') + +function missile:initialize(world,x,y,missile_speed) + + self.xorigin = x + self.yorigin = y + self.width = 10 + self.height = 8 + + self.body = love.physics.newBody(world,x,y,'kinematic') + self.body:setBullet(true) + self.body:setLinearVelocity(self:getInitialLinearVelocity(missile_speed)) + + self.shape = love.physics.newRectangleShape(x,y,self.width,self.height) + + self.fixture = love.physics.newFixture(self.body, self.shape, 0.1) + +end + +function missile:getInitialLinearVelocity(speed) + + local rate = (9 - speed) * 2 + local xcoords = {95,105,110,120,690,169,240,554,625,696,683,550} + + vx = xcoords[math.random(1,12)] - self.xorigin + vy = 500 - self.yorigin + + return vx/rate,vy/rate + +end + +function missile:draw(tail_color, color) + + love.graphics.setColor(tail_color) + love.graphics.line(self.xorigin,self.yorigin,self.xorigin + self.height,self.yorigin,self.body:getX() + 2,self.body:getY(),self.body:getX(),self.body:getY(),self.xorigin,self.yorigin) + + love.graphics.setColor(color) + love.graphics.rectangle('fill',self.body:getX(),self.body:getY(),self.width,self.height) + +end \ No newline at end of file diff --git a/Games/Medieval RPG/missile-command-master/missile.png b/Games/Medieval RPG/missile-command-master/missile.png new file mode 100644 index 0000000000..0996bec6de Binary files /dev/null and b/Games/Medieval RPG/missile-command-master/missile.png differ diff --git a/Games/Medieval RPG/missile-command-master/missle_command_screenshot.png b/Games/Medieval RPG/missile-command-master/missle_command_screenshot.png new file mode 100644 index 0000000000..0996bec6de Binary files /dev/null and b/Games/Medieval RPG/missile-command-master/missle_command_screenshot.png differ diff --git a/Games/Medieval RPG/missile-command-master/score.lua b/Games/Medieval RPG/missile-command-master/score.lua new file mode 100644 index 0000000000..1d44295853 --- /dev/null +++ b/Games/Medieval RPG/missile-command-master/score.lua @@ -0,0 +1,25 @@ +score = class('score') + +function score:initialize() + + self.total = 0 + +end + +function score:add(num) + + self.total = self.total + num + +end + +function score:del(num) + + self.total = self.total - num + +end + +function score:draw() + + love.graphics.print(self.total,720,10) + +end \ No newline at end of file diff --git a/README.md b/README.md index 870fc6e5e1..57864e643d 100644 --- a/README.md +++ b/README.md @@ -366,6 +366,8 @@ This repository also provides one such platforms where contributers come over an | [Ball and Paddle game](https://github.com/kunjgit/GameZone/tree/main/Games/Ball-And-Paddle-Game) | |[Harry Potter Wizards Quiz](https://github.com/kunjgit/GameZone/tree/main/Games/Harry_Potter_Wizards_Quiz)| +|[Medieval RPG](https://github.com/kunjgit/GameZone/tree/main/Games/Medieval RPG)| + </center>