commit
5f6c39999d
14 changed files with 546 additions and 0 deletions
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
local love = require "love" |
||||
|
||||
function Ban(x, y, angle) |
||||
local BAN_SPEED = 300 -- ban hammer speed in pixel/second |
||||
local EXPLODE_DURATION = 0.2 |
||||
|
||||
return { |
||||
sprite = love.graphics.newImage("assets/ban.png"), |
||||
x = x, |
||||
y = y, |
||||
x_vel = BAN_SPEED * math.sin(angle) / love.timer.getFPS(), |
||||
y_vel = -BAN_SPEED * math.cos(angle) / love.timer.getFPS(), |
||||
distance = 0, -- distance traveled |
||||
exploding = 0, -- 0 not exploding, 1 exploding, 2 done exploding |
||||
explode_time = 0, |
||||
|
||||
|
||||
draw = function (self, faded) |
||||
if self.exploding < 1 then |
||||
love.graphics.draw(self.sprite, self.x, self.y, angle, 0.4, 0.4, self.sprite:getWidth() / 2, self.sprite:getHeight() / 2) |
||||
end |
||||
end, |
||||
|
||||
move = function (self) |
||||
self.x = self.x + self.x_vel |
||||
self.y = self.y + self.y_vel |
||||
|
||||
if self.explode_time > 0 then |
||||
self.exploding = 1 |
||||
end |
||||
-- increase the distance traveled |
||||
self.distance = self.distance + math.sqrt((self.x_vel ^ 2) + (self.y_vel ^ 2)) |
||||
end, |
||||
|
||||
explode = function(self) |
||||
self.explode_time = math.ceil(EXPLODE_DURATION * love.timer.getFPS() / 100) |
||||
|
||||
if self.explode_time > EXPLODE_DURATION then |
||||
self.exploding = 2 |
||||
end |
||||
end |
||||
} |
||||
end |
||||
|
||||
return Ban |
||||
@ -0,0 +1,84 @@
@@ -0,0 +1,84 @@
|
||||
local love = require "love" |
||||
|
||||
local Text = require "Text" |
||||
|
||||
function Button(func, text_color, button_color, width, height, text, text_align, font_size, button_x, button_y, text_x, text_y) |
||||
local btn_text = {} |
||||
func = func or function() print("This button has no function attached") end |
||||
|
||||
if text_y then |
||||
btn_text.y = text_y + button_y |
||||
else |
||||
btn_text.y = button_y |
||||
end |
||||
|
||||
if text_x then |
||||
btn_text.x = text_x + button_x |
||||
else |
||||
btn_text.x = button_x |
||||
end |
||||
return { |
||||
text_color = text_color or { r = 1, g = 1, b = 1 }, -- white |
||||
button_color = button_color or { r = 0, g = 0, b = 0 }, -- black |
||||
width = width or 100, |
||||
height = height or 100, |
||||
text = text or "No text added", |
||||
text_x = text_x or button_x or 0, |
||||
text_y = text_y or button_y or 0, |
||||
button_x = button_x or 0, |
||||
button_y = button_y or 0, |
||||
text_component = Text( |
||||
text, |
||||
btn_text.x, |
||||
btn_text.y, |
||||
font_size, |
||||
false, |
||||
false, |
||||
width, |
||||
text_align, |
||||
1 |
||||
), |
||||
|
||||
setButtonColor = function (self, red, green, blue) |
||||
self.button_color = { r = red, g = green, b = blue} |
||||
end, |
||||
|
||||
setTextColor = function (self, red, green, blue) |
||||
self.text_color = { r = red, g = green, b = blue} |
||||
end, |
||||
|
||||
checkHover = function (self, mouse_x, mouse_y, cursor_radius) |
||||
if (mouse_x + cursor_radius >= self.button_x) and (mouse_x - cursor_radius <= self.button_x + self.width) then |
||||
if (mouse_y + cursor_radius >= self.button_y) and (mouse_y - cursor_radius <= self.button_y + self.height) then |
||||
return true |
||||
end |
||||
end |
||||
|
||||
return false |
||||
end, |
||||
|
||||
click = function (self) |
||||
func() |
||||
end, |
||||
|
||||
draw = function (self) |
||||
love.graphics.setColor(self.button_color["r"], self.button_color["g"], self.button_color["b"]) |
||||
love.graphics.rectangle("fill", self.button_x, self.button_y, self.width, self.height) |
||||
|
||||
self.text_component:setColor(self.text_color["r"], self.text_color["g"], self.text_color["b"]) |
||||
self.text_component:draw() |
||||
|
||||
love.graphics.setColor(1, 1, 1) |
||||
end, |
||||
|
||||
getPos = function (self) |
||||
return self.button_x, self.button_y |
||||
end, |
||||
|
||||
getTextPos = function (self) |
||||
return self.text_x, self.text_y |
||||
end |
||||
} |
||||
end |
||||
|
||||
return Button |
||||
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
require "globals" |
||||
local love = require "love" |
||||
local lg = love.graphics |
||||
|
||||
|
||||
function Chat(x, y, level) |
||||
local CHAT_SPEED = math.random(50) + (level * 2) |
||||
local vel = -1 |
||||
|
||||
if math.random() < 0.5 then |
||||
vel = 1 |
||||
end |
||||
|
||||
return { |
||||
sprite = lg.newImage("assets/chat.png"), |
||||
x = x, |
||||
y = y, |
||||
x_vel = math.random() * CHAT_SPEED * vel, |
||||
y_vel = math.random() * CHAT_SPEED * vel, |
||||
radius = 30, |
||||
|
||||
draw = function(self) |
||||
lg.draw(self.sprite, self.x, self.y, 0, 1, 1, self.sprite:getWidth() / 2, self.sprite:getHeight() / 2) |
||||
lg.circle("line", self.x, self.y, self.radius) |
||||
end, |
||||
|
||||
move = function(self, dt) |
||||
self.x = self.x + self.x_vel * dt |
||||
self.y = self.y + self.y_vel * dt |
||||
|
||||
if self.x + self.radius < 0 then |
||||
self.x = love.graphics.getWidth() + self.radius |
||||
elseif self.x - self.radius > love.graphics.getWidth() then |
||||
self.x = -self.radius |
||||
end |
||||
|
||||
if self.y + self.radius < 0 then |
||||
self.y = love.graphics.getHeight() + self.radius |
||||
elseif self.y - self.radius > love.graphics.getHeight() then |
||||
self.y = -self.radius |
||||
end |
||||
end, |
||||
|
||||
destroy = function(self, chat_table, index) |
||||
table.remove(chat_table, index) |
||||
end |
||||
} |
||||
end |
||||
|
||||
return Chat |
||||
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
local love = require "love" |
||||
|
||||
local Chat = require "chat" |
||||
function Game() |
||||
return { |
||||
state = { |
||||
menu = false, |
||||
paused = false, |
||||
running = true, |
||||
ended = false, |
||||
}, |
||||
|
||||
level = 5, |
||||
|
||||
changeGameState = function(self, state) |
||||
self.state.menu = state == "menu" |
||||
self.state.paused = state == "paused" |
||||
self.state.running = state == "running" |
||||
self.state.ended = state == "ended" |
||||
end, |
||||
|
||||
startNewGame = function (self, player) |
||||
self:changeGameState("running") |
||||
|
||||
chats = {} |
||||
|
||||
local chat_x = math.floor(math.random(love.graphics.getWidth() )) |
||||
local chat_y = math.floor(math.random(love.graphics.getHeight())) |
||||
|
||||
table.insert(chats, 1, Chat(chat_x, chat_y, self.level)) |
||||
table.insert(chats, 2, Chat(chat_x, chat_y, self.level)) |
||||
table.insert(chats, 3, Chat(chat_x, chat_y, self.level)) |
||||
table.insert(chats, 4, Chat(chat_x, chat_y, self.level)) |
||||
|
||||
end |
||||
} |
||||
end |
||||
|
||||
return Game |
||||
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
local love = require "love" |
||||
|
||||
local Button = require "Button" |
||||
|
||||
function Menu(game, player) |
||||
local funcs = { |
||||
newGame = function () |
||||
game:startNewGame(player) |
||||
end, |
||||
quitGame = function () |
||||
love.event.quit() |
||||
end, |
||||
} |
||||
|
||||
local buttons = { |
||||
Button(funcs.newGame, nil, nil, love.graphics.getWidth() / 3, 50, "New Game", "center", "h3", love.graphics.getWidth() / 3, love.graphics.getHeight() * 0.25), |
||||
Button(nil, nil, nil, love.graphics.getWidth() / 3, 50, "Settings", "center", "h3", love.graphics.getWidth() / 3, love.graphics.getHeight() * 0.4), |
||||
Button(funcs.quitGame, nil, nil, love.graphics.getWidth() / 3, 50, "Quit", "center", "h3", love.graphics.getWidth() / 3, love.graphics.getHeight() * 0.55), |
||||
} |
||||
|
||||
return { |
||||
focused = "", |
||||
run = function (self, clicked) |
||||
local mouse_x, mouse_y = love.mouse.getPosition() |
||||
for name, button in pairs(buttons) do |
||||
if button:checkHover(mouse_x, mouse_y, 10) then |
||||
if clicked then |
||||
button:click() |
||||
end |
||||
|
||||
self.focused = name |
||||
|
||||
button:setTextColor(0.8, 0.2, 0.2) |
||||
else |
||||
button:setTextColor(1, 1, 1) |
||||
end |
||||
end |
||||
end, |
||||
|
||||
draw = function (self) |
||||
for _, button in pairs(buttons) do |
||||
button:draw() |
||||
end |
||||
end |
||||
} |
||||
end |
||||
|
||||
return Menu |
||||
@ -0,0 +1,108 @@
@@ -0,0 +1,108 @@
|
||||
require "globals" |
||||
local love = require "love" |
||||
|
||||
|
||||
function Player(debugging) |
||||
local lg = love.graphics |
||||
local MAX_BAN = 60 |
||||
|
||||
return { |
||||
sprite = lg.newImage('assets/prime.png'), |
||||
x = 300, |
||||
y = 300, |
||||
angle = 0, |
||||
facing = 0, -- get the angle the player is facing so we know how to shoot the ban hammers |
||||
speed = 80, |
||||
rotation_speed = 1, |
||||
thrusting = false, |
||||
bans = {}, |
||||
thrust = { |
||||
x = 0, |
||||
y = 0, |
||||
speed = 1 |
||||
}, |
||||
draw = function(self) |
||||
lg.draw(player.sprite, player.x, player.y, player.angle, 0.5, 0.5, player.sprite:getWidth() / 2, player.sprite:getHeight() / 2) |
||||
|
||||
-- draw ban hammers |
||||
for _, ban in pairs(self.bans) do |
||||
ban:draw() |
||||
end |
||||
end, |
||||
shootBan = function (self) |
||||
if (#self.bans <= MAX_BAN) then |
||||
table.insert(self.bans, Ban( |
||||
self.x, |
||||
self.y, |
||||
player.facing |
||||
)) |
||||
end |
||||
end, |
||||
destroyBan = function (self, index) |
||||
print(self.ban, index) |
||||
table.remove(self.bans, index) |
||||
end, |
||||
|
||||
movePlayer = function (self, dt) |
||||
local FPS = love.timer.getFPS() |
||||
local friction = 0.7 |
||||
|
||||
if love.keyboard.isDown('left') then |
||||
self.angle = self.angle - self.rotation_speed * dt |
||||
self.facing = self.angle |
||||
print(self.facing) |
||||
end |
||||
if love.keyboard.isDown('right') then |
||||
self.angle = self.angle + self.rotation_speed * dt |
||||
self.facing = self.angle |
||||
end |
||||
|
||||
if self.thrusting then |
||||
self.thrust.x = self.thrust.x + self.thrust.speed * math.sin(self.angle) / FPS |
||||
self.thrust.y = self.thrust.y - self.thrust.speed * math.cos(self.angle) / FPS |
||||
else |
||||
-- applies friction to stop the player |
||||
if self.thrust.x ~= 0 or self.thrust.y ~= 0 then |
||||
self.thrust.x = self.thrust.x - friction * self.thrust.x / FPS |
||||
self.thrust.y = self.thrust.y - friction * self.thrust.y / FPS |
||||
end |
||||
end |
||||
|
||||
self.x = self.x + self.thrust.x |
||||
self.y = self.y + self.thrust.y |
||||
|
||||
-- make sure the player can't go off screen on x axis |
||||
if self.x + (self.sprite:getWidth() / 2) < 0 then |
||||
self.x = love.graphics.getWidth() + (self.sprite:getWidth() / 2) |
||||
elseif self.x - (self.sprite:getWidth() / 2) > love.graphics.getWidth() then |
||||
self.x = -(self.sprite:getWidth() / 2) |
||||
end |
||||
|
||||
-- make sure the player can't go off screen on y axis |
||||
if self.y + (self.sprite:getHeight() / 2) < 0 then |
||||
self.y = love.graphics.getHeight() + (player.sprite:getHeight() / 2) |
||||
elseif self.y - (self.sprite:getHeight() / 2) > love.graphics.getHeight() then |
||||
self.y = -(self.sprite:getHeight() / 2) |
||||
end |
||||
|
||||
-- this will move the ban |
||||
for index, ban in pairs(self.bans) do |
||||
ban:move() |
||||
|
||||
BAN_DISTANCE = 0.6 |
||||
|
||||
if (ban.distance > BAN_DISTANCE * love.graphics.getWidth()) and ban.exploding == 0 then |
||||
ban:explode(self, index) |
||||
end -- endif |
||||
|
||||
if ban.exploding == 0 then -- 0 -> ban not exploding |
||||
ban:move() |
||||
elseif ban.exploding == 2 then -- 2 -> ban is done exploding |
||||
self.destroyBan(self, index) |
||||
end |
||||
end -- endfor |
||||
end --end movePlayer |
||||
} -- end player |
||||
end |
||||
|
||||
return Player |
||||
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
local love = require "love" |
||||
|
||||
function Text(text, x, y, font_size, fade_in, fade_out, wrap_width, align, opacity) |
||||
font_size = font_size or "p" |
||||
fade_in = fade_in or false |
||||
fade_out = fade_out or false |
||||
wrap_width = wrap_width or love.graphics.getWidth() |
||||
align = align or "left" |
||||
opacity = opacity or 1 |
||||
|
||||
local TEXT_FADE_DUR = 5 |
||||
|
||||
local fonts = { |
||||
h1 = love.graphics.newFont(60), |
||||
h2 = love.graphics.newFont(50), |
||||
h3 = love.graphics.newFont(40), |
||||
h4 = love.graphics.newFont(30), |
||||
h5 = love.graphics.newFont(20), |
||||
h6 = love.graphics.newFont(10), |
||||
p = love.graphics.newFont(16), |
||||
} |
||||
|
||||
if fade_in then |
||||
opacity = 0.1 -- if should fade in, then start at low opacity |
||||
end |
||||
|
||||
return { |
||||
text = text, |
||||
x = x, |
||||
y = y, |
||||
opacity = opacity, |
||||
|
||||
colors = { |
||||
r = 1, |
||||
g = 1, |
||||
b = 1 |
||||
}, |
||||
|
||||
setColor = function (self, red, green, blue) |
||||
self.colors.r = red |
||||
self.colors.g = green |
||||
self.colors.b = blue |
||||
end, |
||||
|
||||
draw = function (self, tbl_text, index) |
||||
if self.opacity > 0 then |
||||
-- when pausing, the below will still fade out, it will not be paused |
||||
if fade_in then |
||||
-- only render text if visible, otherwise skip it |
||||
if self.opacity < 1 then |
||||
self.opacity = self.opacity + (1 / TEXT_FADE_DUR / love.timer.getFPS()) |
||||
else |
||||
fade_in = false |
||||
end |
||||
elseif fade_out then |
||||
self.opacity = self.opacity - (1 / TEXT_FADE_DUR / love.timer.getFPS()) |
||||
end |
||||
|
||||
love.graphics.setColor(self.colors.r, self.colors.g, self.colors.b, self.opacity) |
||||
love.graphics.setFont(fonts[font_size]) |
||||
love.graphics.printf(self.text, self.x, self.y, wrap_width, align) |
||||
love.graphics.setFont(fonts["p"]) |
||||
else |
||||
table.remove(tbl_text, index) -- remove yourself once you dissapear |
||||
return false |
||||
end |
||||
|
||||
return true |
||||
end |
||||
} |
||||
end |
||||
|
||||
return Text |
||||
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 35 KiB |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
local love = require "love" |
||||
|
||||
function love.conf(app) |
||||
app.window.width = 1280 |
||||
app.window.height = 720 |
||||
app.window.title = "Z Game" |
||||
app.window.display = 2 |
||||
end |
||||
|
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
function calculateDistance(x1, y1, x2, y2) |
||||
return math.sqrt(((x2 - x1) ^ 2) + ((y2 - y1) ^ 2)) |
||||
end |
||||
@ -0,0 +1,87 @@
@@ -0,0 +1,87 @@
|
||||
local love = require "love" |
||||
local lg = love.graphics |
||||
local lk = love.keyboard |
||||
local Ban = require "Ban" |
||||
local Game = require "Game" |
||||
local Player = require "Player" |
||||
local Menu = require "menu" |
||||
|
||||
math.randomseed(os.time()) |
||||
function love.load() |
||||
local BAN_DISTANCE = 0.6 |
||||
local BAN_SPEED = 500 |
||||
|
||||
player = Player() |
||||
game = Game() |
||||
game:startNewGame(player) |
||||
menu = Menu(game, player) |
||||
end |
||||
|
||||
function love.keypressed(key) |
||||
if game.state.running then |
||||
if key == "escape" then |
||||
game:changeGameState("paused") |
||||
end |
||||
elseif game.state.paused then |
||||
if key == "escape" then |
||||
game:changeGameState("running") |
||||
end |
||||
end -- endif for gamestate |
||||
|
||||
if key == "up" then |
||||
player.thrusting = true |
||||
end |
||||
|
||||
if key == "space" then |
||||
player:shootBan() |
||||
end |
||||
|
||||
end |
||||
|
||||
function love.keyreleased(key) |
||||
if key == "up" then |
||||
player.thrusting = false |
||||
end |
||||
end |
||||
|
||||
function love.mousepressed(x, y, button, istouch, presses) |
||||
|
||||
if button == 1 then |
||||
clickedMouse = true |
||||
end |
||||
end |
||||
|
||||
function love.update(dt) |
||||
if game.state.running then |
||||
player:movePlayer(dt) |
||||
|
||||
for chat_index, chat in pairs(chats) do |
||||
-- we new check to see for ban collision detection |
||||
for _, ban in pairs(player.bans) do |
||||
if calculateDistance(ban.x, ban.y, chat.x, chat.y) < chat.radius then |
||||
ban:explode() -- delete ban |
||||
chat:destroy(chats, chat_index, game) |
||||
end |
||||
end |
||||
|
||||
chat:move(dt) |
||||
end |
||||
|
||||
elseif game.state.menu then |
||||
menu:run(clickedMouse) |
||||
clickedMouse = false |
||||
end |
||||
end |
||||
|
||||
function love.draw() |
||||
if game.state.running then |
||||
player:draw() |
||||
|
||||
for _, chat in pairs(chats) do |
||||
chat:draw() |
||||
end |
||||
|
||||
elseif game.state.paused then |
||||
menu:draw() |
||||
end |
||||
end |
||||
Loading…
Reference in new issue