commit 4fad00895716a074f80e2ab57dc49462d10f78db Author: Marc Di Luzio Date: Sun Mar 19 14:48:01 2017 +0000 Initial commit of work diff --git a/README.md b/README.md new file mode 100644 index 0000000..f656255 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +Pineapple Pizza + +Made for the the Linux Game Jam March 2017 +Requires love2d 0.10 (Super Toast) + +A simple game about protecting pizza from yourself + +This is a propaganga piece made to show pineapples +ruin pizza. Don't deny it, you know it to be true + +Also, it's in space + +The game quits when the pineapple touches a pizza +as what's the point anymore if pizza has been ruined + +Controls : WASD and Space, P to pause and ESC to exit + +Images cliparts.co +BG spacetelescope.org/images/potw1006a +Music toneden.io/mi77ermusic/post/stardust +Sound freesound.org/people/greenvwbeetle/sounds/244654 diff --git a/Stardust.ogg b/Stardust.ogg new file mode 100644 index 0000000..40e38c6 Binary files /dev/null and b/Stardust.ogg differ diff --git a/conf.lua b/conf.lua new file mode 100644 index 0000000..5b4540d --- /dev/null +++ b/conf.lua @@ -0,0 +1,8 @@ +-- ================================================= -- +-- Config +function love.conf(t) + t.identity = "pineapple_pizza" + t.window.title = "Pineapple Pizza" + t.window.width = 360 + t.window.height = 640 +end diff --git a/fireball.png b/fireball.png new file mode 100644 index 0000000..889e887 Binary files /dev/null and b/fireball.png differ diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..ee7d6a5 --- /dev/null +++ b/license.txt @@ -0,0 +1,14 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + diff --git a/main.lua b/main.lua new file mode 100644 index 0000000..4638ced --- /dev/null +++ b/main.lua @@ -0,0 +1,442 @@ +-- ===================================================== -- +-- ____ _ _ ____ _ +-- | _ \(_)_ __ ___ __ _ _ __ _ __ | | ___ | _ \(_)__________ _ +-- | |_) | | '_ \ / _ \/ _` | '_ \| '_ \| |/ _ \ | |_) | |_ /_ / _` | +-- | __/| | | | | __/ (_| | |_) | |_) | | __/ | __/| |/ / / / (_| | +-- |_| |_|_| |_|\___|\__,_| .__/| .__/|_|\___| |_| |_/___/___\__,_| +-- |_| |_| +-- Made for the the Linux Game Jam March 2017 +-- Requires love2d 0.10 (Super Toast) +-- +-- A simple game about protecting pizza from yourself +-- +-- This is a propaganga piece made to show pineapples +-- ruin pizza. Don't deny it, you know it to be true +-- +-- Also, it's in space +-- +-- The game quits when the pineapple touches a pizza +-- as what's the point anymore if pizza has been ruined +-- +-- Controls : WASD and Space, P to pause and ESC to exit +-- +-- ===================================================== -- +-- +-- Images cliparts.co +-- BG spacetelescope.org/images/potw1006a +-- Music toneden.io/mi77ermusic/post/stardust +-- Sound freesound.org/people/greenvwbeetle/sounds/244654 +-- +-- ===================================================== -- + +-- ===================================================== -- +-- Settings + +-- Whole scene properties +kppm = 64 -- Pixels per metre +kwidth = 0 +kheight = 0 + +-- player properties +kplayerThrust = 30000 +kplayerMaxV = 350 +kplayerFriction = 5 + +-- Bullet info +knumBullets = 3 +kbullRadius = 10 +kbulletReturnForce = 300 +kbulletMaxV = 400 + +-- Enemy Info +knumEnemies = 50 +kenemySpawnStartRate = 2 + +-- Music volume +kmusicVolume = 0.05 + +-- Settings +kdifficultyFactor = 1.02 + +-- ===================================================== -- +-- Objects + +-- The physics world +world = {} + +-- Arena Stuff +bounds = {} +bounds.ground = {} +bounds.lwall = {} +bounds.rwall = {} +bounds.ceil = {} + +-- The player +ktypePlayer = {} +player = {} +player.type = ktypePlayer + +-- Bullets +ktypeBullet = {} +bullets = {} +for i=1,knumBullets do + table.insert(bullets, {}) +end +for key,bull in pairs(bullets) do + bull.projectile = false + bull.returning = false + bull.type = ktypeBullet +end + +-- Enemies +ktypeEnemy = {} +enemySpawnRate = kenemySpawnStartRate +enemies = {} +for i=1,knumEnemies do + table.insert(enemies, {}) +end +for key,enemy in pairs(enemies) do + enemy.alive =false + enemy.type = ktypeEnemy +end + +-- Score +score = 0 +paused = true + +-- ===================================================== -- +-- Load +function love.load() + + -- Store some variables + kwidth, kheight = love.graphics.getDimensions() + + -- Create images + imageBG = love.graphics.newImage("space.png") + imagePlayer = love.graphics.newImage("pineapple.png") + imageBullet = love.graphics.newImage("fireball.png") + imageEnemy = love.graphics.newImage("pizza.png") + + -- Load sound + music = love.audio.newSource("Stardust.ogg") + music:setLooping(true) + music:setVolume(kmusicVolume) + music:play() + + soundPop = love.audio.newSource("pop.ogg","static") + + -- Create a physics world + love.physics.setMeter(kppm) + world = love.physics.newWorld( 0 , 0, true ) + world:setCallbacks(beginContact, endConact, preSolve, postSolve) + + -- Create the ground (and walls) + bounds.ground.body = love.physics.newBody(world, kwidth/2, kheight) + bounds.ground.shape = love.physics.newRectangleShape( kwidth, 1 ) + bounds.lwall.body = love.physics.newBody(world, 0, kheight/2) + bounds.lwall.shape = love.physics.newRectangleShape( 1, kheight ) + bounds.rwall.body = love.physics.newBody(world, kwidth, kheight/2) + bounds.rwall.shape = love.physics.newRectangleShape( 1, kheight ) + bounds.ceil.body = love.physics.newBody(world, kwidth/2, 0) + bounds.ceil.shape = love.physics.newRectangleShape( kwidth, 1 ) + + for key,bound in pairs(bounds) do + bound.fixture = love.physics.newFixture( bound.body, bound.shape ) + bound.fixture:setCategory(1) + end + + -- Create the player + player.body = love.physics.newBody(world, kwidth/2, kheight-40, "dynamic") + player.shape = love.physics.newRectangleShape(0, 0, 20, 40) + player.fixture = love.physics.newFixture(player.body, player.shape ) + player.body:setFixedRotation(true) + player.body:setLinearDamping(kplayerFriction) + player.fixture:setCategory(2) + player.fixture:setUserData(player) + + -- Create the bullets + for key,bull in pairs(bullets) do + x, y = player.body:getPosition() + x, y = x + math.random(-30,30), y + math.random(-30,30) + bull.body = love.physics.newBody(world, x, y, "dynamic") + bull.shape = love.physics.newCircleShape(kbullRadius) + bull.fixture = love.physics.newFixture(bull.body, bull.shape) + bull.fixture:setCategory(3) + bull.fixture:setMask(1,2,3) -- bullets don't hit wall, the player, or eachother + bull.fixture:setUserData(bull) + bull.image = imageBullet + end + + -- Create the enemies + enemyTimer = love.timer.getTime() + enemyScale = 1 + for key,enemy in pairs(enemies) do + enemy.body = love.physics.newBody(world, kwidth/2, -100, "dynamic") + enemy.shape = love.physics.newCircleShape(10 * enemyScale) + enemy.scale = enemyScale + enemy.fixture = love.physics.newFixture(enemy.body, enemy.shape) + enemy.fixture:setCategory(4) + enemy.fixture:setMask(1,4) -- enemies don't hit wall or eachother + enemy.fixture:setUserData(enemy) + enemyScale = enemyScale + 0.1 + end + + -- Load in save file + local savedatachunk = love.filesystem.load( "savedata" ) + if savedatachunk then + savedata = savedatachunk() + else + savedata = {} + savedata.highscore = 0 + savedata.fails = 0 + end +end + +-- ===================================================== -- +-- Update +function love.update(dt) + if paused then + music:pause() + return + else + music:resume() + end + + -- Keyboard controls for player + local dx, dy = 0, 0 + if love.keyboard.isDown("left") then + dx = dx - kplayerThrust + end + if love.keyboard.isDown("right") then + dx = dx + kplayerThrust + end + if love.keyboard.isDown("up") then + dy = dy - kplayerThrust + end + if love.keyboard.isDown("down") then + dy = dy + kplayerThrust + end + player.body:applyForce( dx*dt, dy*dt ) + + -- Limit player max velocity + local vx, vy = player.body:getLinearVelocity() + local vel = math.sqrt(vx*vx + vy*vy) + if vel > kplayerMaxV then + vx = vx/vel * kplayerMaxV + vy = vy/vel * kplayerMaxV + player.body:setLinearVelocity(vx,vy) + end + + -- handle the enemies + local spawnEnemy = love.timer.getTime() - enemyTimer > enemySpawnRate + for key,enemy in pairs(enemies) do + -- alive enemies should slowly drop + if enemy.alive then + local x, y = enemy.body:getPosition() + if y > kheight then + enemy.alive = false + end + else + enemy.body:setPosition(-100,-100) -- innactive enemies off screen + if spawnEnemy then + spawnEnemy = false + enemyTimer = love.timer.getTime() -- reset the timer + enemy.body:setPosition( math.random(0,kwidth), 0 ) + enemy.body:setLinearVelocity(math.random(-20,20),math.random(50,200)) + enemy.alive = true + end + end + end + + -- Sort out the bullets + local px, py = player.body:getPosition() + for key,bull in pairs(bullets) do + local bx, by = bull.body:getPosition() + -- non projectiles orbit the player + if not bull.projectile then + -- Get the delta to the player + local dx, dy = px-bx, py-by + bull.body:applyForce( dx * kbulletReturnForce * dt, dy * kbulletReturnForce * dt ) + + -- Account for returned bullets + local dmag = math.sqrt(dx*dx + dy*dy) + if dmag < bull.shape:getRadius()*3 then + bull.returning = false + end + + -- limit vel + local vx, vy = bull.body:getLinearVelocity() + local vel = math.sqrt(vx*vx + vy*vy) + if vel > kbulletMaxV then + vx = vx/vel * kbulletMaxV + vy = vy/vel * kbulletMaxV + bull.body:setLinearVelocity(vx,vy) + end + -- otherwise they fly and come back + else + if by < 0 then + bull.projectile = false + bull.returning = true + end + end + end + + -- Update the physics world last + world:update(dt) +end + +-- ===================================================== -- +-- Key presses +function love.keypressed( key, sc, isrepeat ) + + -- Fire + if key == "space" then + -- find a bullet + for key,bull in pairs(bullets) do + if not bull.projectile and not bull.returning then + bull.projectile = true + bull.body:setPosition(player.body:getPosition()) + bull.body:setLinearVelocity( 0, -1000 ) + break + end + end + + -- Pause + elseif key == "p" then + paused = not paused + + -- Quit + elseif key == "escape" then + love.event.quit() + end +end + +-- ===================================================== -- +-- Draw +function love.draw() + + -- Draw the BG + love.graphics.setColor( 128,128,128,256 ) + love.graphics.draw( imageBG, kwidth/2, kheight/2, love.timer.getTime()/10, 0.8, 0.8, 600, 600) + + -- If we're paused + if paused then + love.graphics.setColor( 256,256,256,256 ) + love.graphics.print( " Paused!\n[P] to unpause", kwidth/2, kheight/2, 0, 1, 1, 40 ) + end + + -- Draw the player + local x,y = player.body:getPosition() + love.graphics.setColor( 256,256,256,256 ) + love.graphics.draw( imagePlayer, x, y+5, 0, 0.2, 0.2, 72,170 ) + + -- Draw the enemies + love.graphics.setColor( 256,256,256,256 ) + for key,enemy in pairs(enemies) do + if enemy.alive then + love.graphics.draw( imageEnemy, + enemy.body:getX(), + enemy.body:getY(), + enemy.scale-1, + 0.2*enemy.scale, 0.2*enemy.scale, + 60, 60 ) + end + end + + -- Draw the bullets + for key,bull in pairs(bullets) do + if bull.projectile then + love.graphics.setColor( 256,256,256,256 ) + elseif bull.returning then + love.graphics.setColor( 128,128,128,64 ) + else + love.graphics.setColor( 200,200,200,180 ) + end + love.graphics.draw( bull.image, + bull.body:getX(), bull.body:getY(), + love.timer.getTime()*4, + 0.2, 0.2, + 60, 60 ) + end + + -- Draw the UI + love.graphics.setColor( 256,256,256,256 ) + love.graphics.print( string.format("Pizzas Saved: %i\nHigh Score: %i\nRuined Pizzas: %i", + score, + savedata.highscore, + savedata.fails), 1, 1 ) +end + + +-- ===================================================== -- +-- Quit +function love.quit() + -- Save out the data + local highest = score + if highest < savedata.highscore then highest = savedata.highscore end + love.filesystem.write( "savedata", string.format("return {\nhighscore = %i,\nfails = %i\n}", + highest, + savedata.fails) ) +end + +-- ===================================================== -- +-- Physics callbacks + +-- ie if a and be are type x and y +-- if so, returns them in correct order +function abxy( a, b, x, y ) + if not a or not b then return end + local at, bt = a.type, b.type + if not at or not bt then return + elseif ( at == x and bt == y) then + return a, b + elseif ( bt == x and at == y) then + return b, a + else + return + end +end + +-- called at start of overlap (always) +function beginContact(first, second, collision) + local fd, sd = first:getUserData(), second:getUserData() + + -- Enemies and bullets + local bullet, enemy = abxy( fd, sd, ktypeBullet, ktypeEnemy ) + if bullet and enemy then + if bullet.projectile and enemy.alive then + enemy.alive = false + bullet.projectile = false + bullet.returning = true + score = score + 1 + soundPop:play() + enemySpawnRate = enemySpawnRate/kdifficultyFactor -- speed up spawns + end + end + + local enemy, player = abxy( fd, sd, ktypeEnemy, ktypePlayer ) + if enemy and player then + savedata.fails = savedata.fails + 1 + love.event.quit() + end +end + +-- called after overlap (only if overlap occured) +function endContact(first, second, collision) +end + +-- called before the collision gets resolved +function preSolve(first, second, collision) + local fd, sd = first:getUserData(), second:getUserData() + + -- Don't do any physics collisions for bullets and enemies + local bullet, enemy = abxy( fd, sd, ktypeBullet, ktypeEnemy ) + if bullet and enemy then + collision:setEnabled(false) + end +end + +-- called after collision resolved, with details +function postSolve(first, second, collision, normalimpulse, tangentimpulse) + -- Not needed yet +end diff --git a/package.sh b/package.sh new file mode 100755 index 0000000..1860db6 --- /dev/null +++ b/package.sh @@ -0,0 +1,7 @@ +#!/bin/bash +zip Pineapple\ Pizza.love \ + *.png \ + *.lua \ + *.ogg \ + *.md \ + *.txt diff --git a/pineapple.png b/pineapple.png new file mode 100644 index 0000000..e11dcb2 Binary files /dev/null and b/pineapple.png differ diff --git a/pizza.png b/pizza.png new file mode 100644 index 0000000..1e98b24 Binary files /dev/null and b/pizza.png differ diff --git a/pop.ogg b/pop.ogg new file mode 100644 index 0000000..879903b Binary files /dev/null and b/pop.ogg differ diff --git a/space.png b/space.png new file mode 100644 index 0000000..198261c Binary files /dev/null and b/space.png differ