├── .DS_Store ├── .luacheckrc ├── readme.md ├── gfx └── cards │ ├── CLUBS_1.png │ ├── CLUBS_10.png │ ├── CLUBS_11.png │ ├── CLUBS_12.png │ ├── CLUBS_13.png │ ├── CLUBS_2.png │ ├── CLUBS_3.png │ ├── CLUBS_4.png │ ├── CLUBS_5.png │ ├── CLUBS_6.png │ ├── CLUBS_7.png │ ├── CLUBS_8.png │ ├── CLUBS_9.png │ ├── HEARTS_1.png │ ├── HEARTS_2.png │ ├── HEARTS_3.png │ ├── HEARTS_4.png │ ├── HEARTS_5.png │ ├── HEARTS_6.png │ ├── HEARTS_7.png │ ├── HEARTS_8.png │ ├── HEARTS_9.png │ ├── JOKER_1.png │ ├── JOKER_2.png │ ├── SPADES_1.png │ ├── SPADES_2.png │ ├── SPADES_3.png │ ├── SPADES_4.png │ ├── SPADES_5.png │ ├── SPADES_6.png │ ├── SPADES_7.png │ ├── SPADES_8.png │ ├── SPADES_9.png │ ├── CARD_BACK.png │ ├── DIAMONDS_1.png │ ├── DIAMONDS_10.png │ ├── DIAMONDS_11.png │ ├── DIAMONDS_12.png │ ├── DIAMONDS_13.png │ ├── DIAMONDS_2.png │ ├── DIAMONDS_3.png │ ├── DIAMONDS_4.png │ ├── DIAMONDS_5.png │ ├── DIAMONDS_6.png │ ├── DIAMONDS_7.png │ ├── DIAMONDS_8.png │ ├── DIAMONDS_9.png │ ├── HEARTS_10.png │ ├── HEARTS_11.png │ ├── HEARTS_12.png │ ├── HEARTS_13.png │ ├── SPADES_10.png │ ├── SPADES_11.png │ ├── SPADES_12.png │ └── SPADES_13.png ├── screenshots └── image.png ├── conf.lua ├── helper.lua ├── tooltip.lua ├── button.lua ├── deck.lua ├── menu.lua ├── main.lua ├── card.lua └── player.lua /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/.DS_Store -------------------------------------------------------------------------------- /.luacheckrc: -------------------------------------------------------------------------------- 1 | new_globals = { '_', 'love' } 2 | exclude_files = { '**/.*' } 3 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## MonsterPoker 2 | 3 | ![Game Screenshot](screenshots/image.png) 4 | -------------------------------------------------------------------------------- /gfx/cards/CLUBS_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_1.png -------------------------------------------------------------------------------- /gfx/cards/CLUBS_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_10.png -------------------------------------------------------------------------------- /gfx/cards/CLUBS_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_11.png -------------------------------------------------------------------------------- /gfx/cards/CLUBS_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_12.png -------------------------------------------------------------------------------- /gfx/cards/CLUBS_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_13.png -------------------------------------------------------------------------------- /gfx/cards/CLUBS_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_2.png -------------------------------------------------------------------------------- /gfx/cards/CLUBS_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_3.png -------------------------------------------------------------------------------- /gfx/cards/CLUBS_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_4.png -------------------------------------------------------------------------------- /gfx/cards/CLUBS_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_5.png -------------------------------------------------------------------------------- /gfx/cards/CLUBS_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_6.png -------------------------------------------------------------------------------- /gfx/cards/CLUBS_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_7.png -------------------------------------------------------------------------------- /gfx/cards/CLUBS_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_8.png -------------------------------------------------------------------------------- /gfx/cards/CLUBS_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CLUBS_9.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_1.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_2.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_3.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_4.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_5.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_6.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_7.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_8.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_9.png -------------------------------------------------------------------------------- /gfx/cards/JOKER_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/JOKER_1.png -------------------------------------------------------------------------------- /gfx/cards/JOKER_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/JOKER_2.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_1.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_2.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_3.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_4.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_5.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_6.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_7.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_8.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_9.png -------------------------------------------------------------------------------- /screenshots/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/screenshots/image.png -------------------------------------------------------------------------------- /gfx/cards/CARD_BACK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/CARD_BACK.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_1.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_10.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_11.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_12.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_13.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_2.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_3.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_4.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_5.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_6.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_7.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_8.png -------------------------------------------------------------------------------- /gfx/cards/DIAMONDS_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/DIAMONDS_9.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_10.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_11.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_12.png -------------------------------------------------------------------------------- /gfx/cards/HEARTS_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/HEARTS_13.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_10.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_11.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_12.png -------------------------------------------------------------------------------- /gfx/cards/SPADES_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dimillian/MonsterPoker/main/gfx/cards/SPADES_13.png -------------------------------------------------------------------------------- /conf.lua: -------------------------------------------------------------------------------- 1 | function love.conf(t) 2 | t.window.title = "Battle Monster" 3 | t.window.width = 800 4 | t.window.height = 600 5 | t.window.resizable = true 6 | end 7 | -------------------------------------------------------------------------------- /helper.lua: -------------------------------------------------------------------------------- 1 | 2 | function drawCardImage(image, x, y, scale) 3 | local imageWidth, imageHeight = image:getDimensions() 4 | love.graphics.draw(image, x, y, 0, 5 | (cardWidth() * scale) / imageWidth, 6 | (cardHeight() * scale) / imageHeight, 7 | cardWidth() / 2, cardHeight() / 2) 8 | end 9 | 10 | function cardWidth() 11 | local windowWidth = love.graphics.getWidth() 12 | return math.floor(windowWidth * 0.1) 13 | end 14 | 15 | function cardHeight() 16 | local width = cardWidth() 17 | return math.floor(width * 1.25) 18 | end 19 | -------------------------------------------------------------------------------- /tooltip.lua: -------------------------------------------------------------------------------- 1 | Tooltip = {} 2 | Tooltip.__index = Tooltip 3 | 4 | function Tooltip:new(card) 5 | local self = setmetatable({}, Tooltip) 6 | self.card = card 7 | self.width = 120 8 | self.height = 50 9 | self.spacing = 30 10 | return self 11 | end 12 | 13 | function Tooltip:draw(x, y) 14 | local startX = x - 20 15 | local startY = y - self.height - self.spacing 16 | 17 | love.graphics.setColor(0.8, 0.9, 1) 18 | love.graphics.rectangle("fill", startX, startY, self.width, self.height) 19 | love.graphics.setColor(0.5, 0.5, 0.5) 20 | love.graphics.rectangle("line", startX, startY, self.width, self.height) 21 | love.graphics.setColor(0, 0, 0) 22 | love.graphics.print(self.card.value .. " of " .. self.card.suit, startX + 6, startY + 6) 23 | love.graphics.print("Score: " .. CardValue[self.card.value], startX + 6, startY + 26) 24 | love.graphics.setColor(1, 1, 1) 25 | end 26 | -------------------------------------------------------------------------------- /button.lua: -------------------------------------------------------------------------------- 1 | Button = {} 2 | Button.__index = Button 3 | 4 | function Button:new(text, onClick) 5 | local self = setmetatable({}, Button) 6 | self.text = text 7 | self.onClick = onClick 8 | self.isPressed = false 9 | local font = love.graphics.getFont() 10 | self.width = font:getWidth(self.text) + 20 11 | self.height = font:getHeight(self.text) + 10 12 | return self 13 | end 14 | 15 | function Button:draw(x, y) 16 | self.x = x 17 | self.y = y 18 | if self.isPressed then 19 | love.graphics.setColor(0.7, 0.7, 0.7) 20 | else 21 | love.graphics.setColor(0.2, 0.4, 0.8) 22 | end 23 | love.graphics.rectangle("fill", self.x, self.y, self.width, self.height) 24 | love.graphics.setColor(1, 1, 1) 25 | if not self.isPressed then 26 | love.graphics.rectangle("line", self.x, self.y, self.width, self.height) 27 | end 28 | love.graphics.setColor(0, 0, 0) 29 | love.graphics.print(self.text, self.x + 7, self.y + 4) 30 | love.graphics.setColor(1, 1, 1) 31 | end 32 | 33 | function Button:mousepressed(x, y, button, istouch, presses) 34 | if button == 1 then 35 | local mx, my = x, y 36 | if mx >= self.x and mx <= self.x + self.width and my >= self.y and my <= self.y + self.height then 37 | self.isPressed = true 38 | end 39 | end 40 | end 41 | 42 | function Button:mousereleased(x, y, button, istouch, presses) 43 | if button == 1 and self.isPressed then 44 | self.onClick() 45 | self.isPressed = false 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /deck.lua: -------------------------------------------------------------------------------- 1 | require "card" 2 | 3 | Deck = { } 4 | 5 | Deck.__index = Deck 6 | 7 | function Deck:new() 8 | local self = setmetatable({}, Deck) 9 | self.cards = {} 10 | 11 | for suit, _ in pairs(CardSuit) do 12 | for value, _ in pairs(CardValue) do 13 | table.insert(self.cards, Card:new(value, suit)) 14 | end 15 | end 16 | 17 | self:shuffle() 18 | 19 | self.initialCardCount = #self.cards 20 | 21 | return self 22 | end 23 | 24 | function Deck:draw(x, y) 25 | local image = self:getImage() 26 | local drawCount = math.min(self:cardsLeft(), self.initialCardCount) 27 | 28 | for i = 0, drawCount - 1 do 29 | local xOffset = i * 0.1 30 | drawCardImage(image, x + xOffset, y, 1.0) 31 | 32 | end 33 | end 34 | 35 | function Deck:addCard(card) 36 | table.insert(self.cards, card) 37 | self:shuffle() 38 | end 39 | 40 | function Deck:getImage() 41 | if self.image then 42 | return self.image 43 | end 44 | local image = "gfx/cards/CARD_BACK.png" 45 | self.image = love.graphics.newImage(image) 46 | return self.image 47 | end 48 | 49 | function Deck:shuffle() 50 | for i = #self.cards, 2, -1 do 51 | local j = love.math.random(1, i) 52 | self.cards[i], self.cards[j] = self.cards[j], self.cards[i] 53 | end 54 | end 55 | 56 | function Deck:drawCard() 57 | if #self.cards == 0 then 58 | return nil 59 | end 60 | return table.remove(self.cards, 1) 61 | end 62 | 63 | function Deck:cardsLeft() 64 | return #self.cards 65 | end 66 | -------------------------------------------------------------------------------- /menu.lua: -------------------------------------------------------------------------------- 1 | Menu = {} 2 | Menu.__index = Menu 3 | 4 | MAIN_MENU_ITEMS = { 5 | START_GAME = "Start Game", 6 | OPTIONS = "Options", 7 | QUIT = "Quit" 8 | } 9 | 10 | OPTIONS_MENU_ITEMS = { 11 | BACK = "Back" 12 | } 13 | 14 | function mainMenuItems() 15 | return {MAIN_MENU_ITEMS.START_GAME, MAIN_MENU_ITEMS.OPTIONS, 16 | MAIN_MENU_ITEMS.QUIT} 17 | end 18 | 19 | function Menu:new(items, x, y, selectedColor, unselectedColor) 20 | local self = setmetatable({}, Menu) 21 | self.items = items or {} 22 | self.selectedIndex = 1 23 | self.x = x or 50 24 | self.y = y or 50 25 | self.selectedColor = selectedColor or {1, 1, 0} 26 | self.unselectedColor = unselectedColor or {1, 1, 1} 27 | self.spacing = 10 28 | return self 29 | end 30 | 31 | function Menu:keypressed(key) 32 | if key == "down" then 33 | self.selectedIndex = math.min(self.selectedIndex + 1, #self.items) 34 | elseif key == "up" then 35 | self.selectedIndex = math.max(self.selectedIndex - 1, 1) 36 | end 37 | end 38 | 39 | function Menu:draw() 40 | local font = love.graphics.getFont() 41 | local fontHeight = font:getHeight() 42 | 43 | for i, item in ipairs(self.items) do 44 | local itemY = self.y + (i - 1) * (fontHeight + self.spacing) 45 | if i == self.selectedIndex then 46 | love.graphics.setColor(unpack(self.selectedColor)) 47 | love.graphics.print("> " .. item, self.x, itemY) 48 | else 49 | love.graphics.setColor(unpack(self.unselectedColor)) 50 | love.graphics.print(item, self.x, itemY) 51 | end 52 | end 53 | love.graphics.setColor(1, 1, 1) -- Reset color 54 | end 55 | 56 | function Menu:getSelectedItem() 57 | return self.items[self.selectedIndex] 58 | end 59 | -------------------------------------------------------------------------------- /main.lua: -------------------------------------------------------------------------------- 1 | require "deck" 2 | require "card" 3 | require "player" 4 | require "menu" 5 | 6 | GameState = { 7 | MAIN_MENU = 1, 8 | GAME = 2, 9 | OPTIONS = 3, 10 | } 11 | 12 | local gameState = GameState.MAIN_MENU 13 | 14 | function love.load() 15 | player = Player:new() 16 | ai = Player:new() 17 | mainMenu = Menu:new(mainMenuItems()) 18 | end 19 | 20 | function love.update(dt) 21 | if gameState == GameState.GAME then 22 | player:update(dt) 23 | end 24 | end 25 | 26 | function love.draw() 27 | if gameState == GameState.MAIN_MENU then 28 | mainMenu:draw() 29 | elseif gameState == GameState.GAME then 30 | player:draw() 31 | end 32 | end 33 | 34 | function love.keypressed(key) 35 | 36 | if gameState == GameState.MAIN_MENU then 37 | mainMenu:keypressed(key) 38 | elseif gameState == GameState.GAME then 39 | player:keypressed(key) 40 | end 41 | 42 | if key == "space" then 43 | if gameState == GameState.MAIN_MENU then 44 | local item = mainMenu:getSelectedItem() 45 | if item == MAIN_MENU_ITEMS.START_GAME then 46 | gameState = GameState.GAME 47 | elseif item == MAIN_MENU_ITEMS.OPTIONS then 48 | gameState = GameState.OPTIONS 49 | elseif item == MAIN_MENU_ITEMS.QUIT then 50 | love.event.quit() 51 | end 52 | end 53 | elseif key == "escape" then 54 | if gameState == GameState.GAME or gameState == GameState.OPTIONS then 55 | gameState = GameState.MAIN_MENU 56 | elseif gameState == GameState.MAIN_MENU then 57 | love.event.quit() 58 | end 59 | end 60 | end 61 | 62 | function love.mousepressed(x, y, button, istouch, presses) 63 | player:mousepressed(x, y, button, istouch, presses) 64 | end 65 | 66 | function love.mousereleased(x, y, button, istouch, presses) 67 | player:mousereleased(x, y, button, istouch, presses) 68 | end 69 | -------------------------------------------------------------------------------- /card.lua: -------------------------------------------------------------------------------- 1 | require "helper" 2 | require "tooltip" 3 | 4 | CardValue = { 5 | ACE = 1, TWO = 2, THREE = 3, FOUR = 4, FIVE = 5, 6 | SIX = 6, SEVEN = 7, EIGHT = 8, NINE = 9, TEN = 10, 7 | JACK = 11, QUEEN = 12, KING = 13 8 | } 9 | 10 | CardSuit = { 11 | HEARTS = "HEARTS", 12 | DIAMONDS = "DIAMONDS", 13 | CLUBS = "CLUBS", 14 | SPADES = "SPADES" 15 | } 16 | 17 | Card = { } 18 | Card.__index = Card 19 | 20 | function Card:new(value, suit, onClick) 21 | assert(CardValue[value], "Invalid card value") 22 | assert(CardSuit[suit], "Invalid card suit") 23 | local self = setmetatable({}, Card) 24 | self.value = value 25 | self.suit = suit 26 | self.currentScale = 1 27 | self.hoverScale = 1.1 28 | self.hoverTime = 0 29 | self.isHovered = false 30 | self.isDragging = false 31 | self.dragOffsetX = 0 32 | self.dragOffsetY = 0 33 | self.x = 0 34 | self.y = 0 35 | self.onClick = onClick 36 | return self 37 | end 38 | 39 | function Card:getValue() 40 | if CardValue[self.value] <= 10 then 41 | return CardValue[self.value] 42 | else 43 | return self.value 44 | end 45 | end 46 | 47 | 48 | function Card:draw(x, y, angle) 49 | self.x = x 50 | self.y = y 51 | 52 | love.graphics.setColor(1, 1, 1) 53 | 54 | local mx, my = love.mouse.getPosition() 55 | local targetScale = 1 56 | local bounceAmplitude = 0.05 57 | local bounceSpeed = 5 58 | 59 | if self.isDragging then 60 | x = mx - self.dragOffsetX 61 | y = my - self.dragOffsetY 62 | elseif self.isHovered then 63 | targetScale = self.hoverScale 64 | self.hoverTime = self.hoverTime + love.timer.getDelta() 65 | else 66 | self.hoverTime = 0 67 | end 68 | 69 | if self.hoverTime > 0 then 70 | targetScale = targetScale + math.sin(self.hoverTime * bounceSpeed) * bounceAmplitude 71 | end 72 | 73 | self.currentScale = self.currentScale + (targetScale - self.currentScale) * 0.1 74 | 75 | if self.hoverTime > 0 then 76 | self:drawImage(x, y) 77 | self:drawTooltip(x, y) 78 | else 79 | love.graphics.push() 80 | love.graphics.translate(self.x + cardWidth() / 2, self.y + cardHeight() / 2) 81 | love.graphics.rotate(angle) 82 | love.graphics.translate(-cardWidth() / 2, -cardHeight() / 2) 83 | self:drawImage(0, 0) 84 | love.graphics.pop() 85 | end 86 | end 87 | 88 | function Card:drawImage(x, y) 89 | local image = self:getImage() 90 | drawCardImage(image, x, y, self.currentScale) 91 | end 92 | 93 | function Card:drawTooltip(x, y) 94 | if not self.tooltip then 95 | self.tooltip = Tooltip:new(self) 96 | end 97 | self.tooltip:draw(x, y) 98 | end 99 | 100 | function Card:update() 101 | local mx, my = love.mouse.getPosition() 102 | if mx >= self.x and mx <= self.x + cardWidth() and my >= self.y and my <= self.y + cardHeight() then 103 | self.isHovered = true 104 | else 105 | self.isHovered = false 106 | end 107 | end 108 | 109 | function Card:getImage() 110 | if self.image then 111 | return self.image 112 | end 113 | local image = "gfx/cards/" .. self.suit .. "_" .. CardValue[self.value] .. ".png" 114 | self.image = love.graphics.newImage(image) 115 | self.image:setFilter("nearest", "nearest") 116 | return self.image 117 | end 118 | 119 | function Card:mousepressed(x, y, button, istouch, presses) 120 | if button == 1 then 121 | local mx, my = x, y 122 | if mx >= self.x and mx <= self.x + cardWidth() and my >= self.y and my <= self.y + cardHeight() then 123 | self.isDragging = true 124 | self.dragOffsetX = mx - self.x 125 | self.dragOffsetY = my - self.y 126 | end 127 | end 128 | end 129 | 130 | function Card:mousereleased(x, y, button, istouch, presses) 131 | if button == 1 then 132 | if self.isDragging then 133 | self.isDragging = false 134 | if self.onClick then 135 | self.onClick() 136 | end 137 | end 138 | end 139 | end 140 | -------------------------------------------------------------------------------- /player.lua: -------------------------------------------------------------------------------- 1 | require "card" 2 | require "button" 3 | 4 | Player = {} 5 | Player.__index = Player 6 | 7 | function Player:new() 8 | local self = setmetatable({}, Player) 9 | self.deck = Deck:new() 10 | self.hand = {} 11 | self.discard = {} 12 | self.maxHandSize = 7 13 | self.score = 0 14 | self.drawCardButton = Button:new("Draw", function() self:drawCard() end) 15 | self.discardCardButton = Button:new("Discard", function() self:discardSelectedCards() end) 16 | return self 17 | end 18 | 19 | function Player:drawCard() 20 | if #self.hand < self.maxHandSize then 21 | local card = self.deck:drawCard() 22 | card.onClick = function() self:selectCard(card) end 23 | table.insert(self.hand, card) 24 | end 25 | end 26 | 27 | 28 | function Player:discardSelectedCards() 29 | local cardsToDiscard = {} 30 | for i = #self.hand, 1, -1 do 31 | local card = self.hand[i] 32 | if card.selected then 33 | table.insert(cardsToDiscard, table.remove(self.hand, i)) 34 | end 35 | end 36 | for _, card in ipairs(cardsToDiscard) do 37 | table.insert(self.discard, card) 38 | end 39 | end 40 | 41 | function Player:selectCard(card) 42 | card.selected = not card.selected 43 | end 44 | 45 | function Player:draw() 46 | love.graphics.setBackgroundColor(0.137, 0.294, 0.137) 47 | love.graphics.print("Player:", 10, 10) 48 | love.graphics.print("Deck: " .. #self.deck.cards, 10, 30) 49 | self:drawDeck() 50 | if self.hand then 51 | self:drawHand() 52 | else 53 | love.graphics.print("No card in hand", 10, 30) 54 | end 55 | self:drawUI() 56 | end 57 | 58 | 59 | function Player:drawDeck() 60 | local x = love.graphics.getWidth() - cardWidth() - 20 61 | local y = love.graphics.getHeight() - cardHeight() - 20 62 | self.deck:draw(x, y) 63 | end 64 | 65 | function Player:calculateCardAngle(index, totalCards) 66 | if totalCards == 1 then 67 | return 0 68 | end 69 | local maxAngle = math.rad(15) 70 | local angleStep = (2 * maxAngle) / (totalCards - 1) 71 | local angle = -maxAngle + (index - 1) * angleStep 72 | return angle 73 | end 74 | 75 | 76 | function Player:drawHand() 77 | love.graphics.print("Hand:" .. #self.hand .. "/" .. self.maxHandSize, 10, 50) 78 | local spacing = 2 79 | local startX = 0 80 | local animationSpeed = 0.1 81 | for i, card in ipairs(self.hand) do 82 | local x = startX + i * (cardWidth() + spacing) 83 | local angle = self:calculateCardAngle(i, #self.hand) 84 | local baseY = love.graphics.getHeight() - cardHeight() - 40 85 | local hoverY = baseY - 20 86 | if card.selected then 87 | hoverY = baseY - 50 88 | end 89 | card.handY = card.handY or baseY 90 | if card.hoverTime > 0 or card.selected then 91 | card.handY = card.handY + (hoverY - card.handY) * animationSpeed 92 | else 93 | card.handY = card.handY + (baseY - card.handY) * animationSpeed 94 | end 95 | card:draw(x, card.handY, card.selected and 0 or angle) 96 | end 97 | end 98 | 99 | function Player:drawUI() 100 | local x = love.graphics.getWidth() - self.drawCardButton.width - 20 101 | local y = love.graphics.getHeight() - self.drawCardButton.height - 150 102 | self.drawCardButton:draw(x, y) 103 | x = love.graphics.getWidth() - self.discardCardButton.width - 20 104 | y = love.graphics.getHeight() - self.discardCardButton.height - 190 105 | self.discardCardButton:draw(x, y) 106 | end 107 | 108 | function Player:update(dt) 109 | for i, card in ipairs(self.hand) do 110 | card:update(dt) 111 | end 112 | end 113 | 114 | function Player:keypressed(key) 115 | if key == "space" then 116 | self:drawCard() 117 | end 118 | end 119 | 120 | function Player:mousepressed(x, y, button, istouch, presses) 121 | self.drawCardButton:mousepressed(x, y, button, istouch, presses) 122 | self.discardCardButton:mousepressed(x, y, button, istouch, presses) 123 | for i, card in ipairs(self.hand) do 124 | card:mousepressed(x, y, button, istouch, presses) 125 | end 126 | end 127 | 128 | function Player:mousereleased(x, y, button, istouch, presses) 129 | self.drawCardButton:mousereleased(x, y, button, istouch, presses) 130 | self.discardCardButton:mousereleased(x, y, button, istouch, presses) 131 | for i, card in ipairs(self.hand) do 132 | card:mousereleased(x, y, button, istouch, presses) 133 | end 134 | end 135 | 136 | function table.contains(table, element) 137 | for i, value in pairs(table) do 138 | if value == element then 139 | return i 140 | end 141 | end 142 | return -1 143 | end 144 | --------------------------------------------------------------------------------