Created
December 1, 2011 17:47
-
-
Save anonymous/1418508 to your computer and use it in GitHub Desktop.
Wizard's Fire for Codea 0.20
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
House = class() | |
-- this class contains info for both houses and towers. It's pretty | |
-- sparse at the moment, but I expect to expand the game with the | |
-- ability to upgrade and rebuild houses | |
HOUSE_DESTROYED = 0 | |
HOUSE_STANDARD = 1 | |
HOUSE_TOWER = 5 | |
function House:init(x) | |
self.x = x | |
self.type = HOUSE_STANDARD | |
end | |
function House:distance(x) | |
return math.abs(self.x - x) | |
end | |
function House:draw() | |
if self.type == HOUSE_DESTROYED then | |
sprite("Small World:Dirt Patch", self.x, 60) | |
elseif self.type == HOUSE_STANDARD then | |
sprite("Small World:House", self.x, 80) | |
elseif self.type == HOUSE_TOWER then | |
sprite("Small World:Watch Tower", self.x, 110) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Level = class() | |
-- This class is mostly a grab bag of variables associated with the | |
-- current round of play, but is also reonsible for drawing level | |
-- and game over messages along with background items. | |
function Level:init(x) | |
self.number = x | |
-- maxMissilies is the number of incoming on screen at one time | |
self.maxMissiles = x * 4 | |
if self.maxMissiles > 12 then | |
self.maxMissiles = 12 | |
end | |
self.missileCount = 0 | |
-- total is the number of missiles in the level | |
self.total = x * 4 + 12 | |
-- launched is how many have already been launched | |
self.launched = 0 | |
self.destroyed = 0 | |
-- endTime marks elapsedTime when final missile is destroyed | |
self.endTime = 0 | |
self.stars = {} | |
self.clouds = {} | |
for i=1, 25 do | |
self.stars[i] = vec2(WIDTH * math.random(), | |
HEIGHT * math.random() + 150) | |
end | |
for i=1, 10 do | |
self.clouds[i] = vec2(WIDTH * math.random() - 100, | |
HEIGHT * math.random() + 250) | |
end | |
self.sun = vec2(WIDTH -110, HEIGHT - 50) | |
end | |
function drawChar(c, x, y, w) | |
-- some letters for level / game over | |
h = w * 2 | |
if c == 'L' then | |
line(x, y, x, y - h) | |
line(x, y - h, x + w, y - h) | |
elseif c == 'E' then | |
line(x, y, x, y - h) | |
line(x, y, x + w, y) | |
line(x, y - h / 2, x + w, y - h / 2) | |
line(x, y - h, x + w, y - h) | |
elseif c == 'V' then | |
line(x, y, x + w / 2, y - h) | |
line(x + w / 2, y - h, x + w, y) | |
elseif c == 'O' then | |
line(x, y, x, y - h) | |
line(x, y - h, x + w, y - h) | |
line(x + w, y - h, x + w, y) | |
line(x, y, x + w, y) | |
elseif c == 'R' then | |
line(x, y, x, y - h) | |
line(x, y, x + w, y - h / 4) | |
line(x + w, y - h / 4, x, y - h / 2) | |
line(x, y - h / 2, x + w, y - h) | |
elseif c == 'G' then | |
line(x, y, x, y - h) | |
line(x, y, x + w, y) | |
line(x, y - h, x + w, y - h) | |
line(x + w, y - h, x + w, y - h / 2) | |
line(x + w / 2, y - h / 2, x + w, y - h / 2) | |
elseif c == 'M' then | |
line(x, y, x, y - h) | |
line(x + w, y, x + w, y - h) | |
line(x, y, x + w / 2, y - h) | |
line(x + w / 2, y - h, x + w, y) | |
elseif c == 'A' then | |
line(x + w / 2, y, x, y - h) | |
line(x + w / 2, y, x + w, y - h) | |
line(x + w / 4, y - h / 2, x + w * 0.75, y - h / 2) | |
end | |
end | |
function Level:drawOver() | |
stroke(255, 153, 0, 255) | |
strokeWidth(8) | |
drawChar('L', 130, 400, 40) | |
drawChar('E', 180, 400, 40) | |
drawChar('V', 230, 400, 40) | |
drawChar('E', 280, 400, 40) | |
drawChar('L', 330, 400, 40) | |
drawChar('O', 430, 400, 40) | |
drawChar('V', 480, 400, 40) | |
drawChar('E', 530, 400, 40) | |
drawChar('R', 580, 400, 40) | |
end | |
function Level:gameOver() | |
stroke(255, 0, 11, 255) | |
strokeWidth(8) | |
drawChar('G', 100, 400, 50) | |
drawChar('A', 160, 400, 50) | |
drawChar('M', 220, 400, 50) | |
drawChar('E', 280, 400, 50) | |
drawChar('O', 420, 400, 50) | |
drawChar('V', 480, 400, 50) | |
drawChar('E', 540, 400, 50) | |
drawChar('R', 600, 400, 50) | |
end | |
function Level:hit() | |
-- a missile is taken out | |
self.destroyed = self.destroyed + 1 | |
if self.destroyed >= self.total then | |
self.endTime = ElapsedTime | |
end | |
end | |
function Level:active() | |
-- check to see if there are more missiles to launch | |
if self.launched < self.total then | |
return true | |
end | |
return false | |
end | |
function Level:over() | |
-- check to see that everything has been destroyed | |
if self.destroyed >= self.total then | |
return true | |
end | |
return false | |
end | |
function Level:draw() | |
-- background | |
if math.modf(self.number / 2) == self.number / 2 then | |
fill(0, 0, 0, 255) | |
rect(0, 190, WIDTH, HEIGHT) | |
fill(13, 13, 13, 255) | |
rect(0, 132, WIDTH, 64) | |
fill(33, 24, 21, 255) | |
rect(0, 100, WIDTH, 32) | |
fill(31, 116, 51, 255) | |
rect(0,0,WIDTH,100) | |
stroke(255, 255, 255, 255) | |
strokeWidth(3) | |
for i = 1, 25 do | |
line(self.stars[i].x, self.stars[i].y, | |
self.stars[i].x, self.stars[i].y) | |
end | |
else | |
fill(152, 158, 221, 255) | |
rect(0, 190, WIDTH, HEIGHT) | |
fill(153, 159, 200, 255) | |
rect(0, 132, WIDTH, 64) | |
fill(162, 169, 184, 255) | |
rect(0, 100, WIDTH, 32) | |
for i=1, 5 do | |
fill(251, 251, 1, i * 50) | |
ellipse(self.sun.x, self.sun.y, 100 - i * 10) | |
self.sun.y = self.sun.y - 0.02 | |
end | |
fill(45, 152, 59, 255) | |
rect(0,0,WIDTH,100) | |
strokeWidth(0) | |
for i=1, 5 do | |
fill(251, 251, 1, i * 50) | |
ellipse(self.sun.x, self.sun.y, 100 - i * 10) | |
self.sun.y = self.sun.y - 0.02 | |
end | |
if self.number > 1 then | |
for i = 1, 10 do | |
sprite("Small World:Dialog Thought", | |
self.clouds[i].x, self.clouds[i].y, 100, 35) | |
self.clouds[i].x = self.clouds[i].x + 0.1 | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Wizard's Fire 0.2 | |
-- Mark Sumner | |
-- devilstower@gmail.com | |
function setup() | |
local i | |
-- the missiles array holds the incoming fire | |
missiles = {} | |
-- the houses array holds buildings, including towers | |
houses = {} | |
-- the shots array holds shots | |
shots = {} | |
-- level has most of the info on diificulty | |
level = Level(1) | |
-- layout buildings | |
for i=1, 7 do | |
houses[i] = House(i * 100 - 98 + 70) | |
end | |
houses[1].type = HOUSE_TOWER | |
houses[7].type = HOUSE_TOWER | |
-- init shots | |
for i= 1, 5 do | |
shots[i] = Shot(0,0,0,0, SHOT_READY) | |
end | |
-- track changes in touch | |
oldTouch = nil | |
score = Score() | |
day = true | |
endTimer = 0 | |
startLevel() | |
end | |
function startLevel() | |
-- reset the missiles | |
local i | |
for i=1, level.maxMissiles do | |
missiles[i] = Missile(WIDTH * math.random(), | |
HEIGHT + 200 * math.random(), 1 + level.number/3) | |
level.launched = level.launched + 1 | |
end | |
end | |
function launchShot(x, y) | |
-- return fire | |
local house | |
local shot | |
local tower | |
-- find nearest tower | |
distance = 1000 | |
tower = 0 | |
for house = 1, 7 do | |
if houses[house].type == HOUSE_TOWER then | |
if houses[house]:distance(x) < distance then | |
distance = houses[house]:distance(x) | |
tower = house | |
end | |
end | |
end | |
if tower == 0 then | |
sound(SOUND_BLIT,111) | |
return nil | |
end | |
for shot = 1, 5 do | |
if shots[shot].status == SHOT_READY then | |
-- launch a shot | |
sound(SOUND_HIT,111) | |
shots[shot]:launch(houses[tower].x, 145, x, y) | |
return nil | |
end | |
end | |
return nil | |
end | |
function houseCount() | |
-- check to see how many houses remain | |
local i | |
local count = 0 | |
for i=1, 7 do | |
if houses[i].type == HOUSE_STANDARD then | |
count = count + 1 | |
end | |
end | |
return count | |
end | |
function drawLandscape() | |
-- houses, towers, & background | |
level:draw() | |
local house | |
for house=1, 7 do | |
houses[house]:draw() | |
end | |
return nil | |
end | |
function draw() | |
-- main loop | |
if math.modf(level.number / 2) == level.number / 2 then | |
day = true | |
else | |
day = false | |
end | |
drawLandscape() | |
score:draw() | |
-- check on launching a shot | |
if CurrentTouch.state == BEGAN and | |
CurrentTouch.state < oldTouch then | |
launchShot(CurrentTouch.x, CurrentTouch.y) | |
end | |
oldTouch = CurrentTouch.state | |
-- update missiles | |
for i=1, level.maxMissiles do | |
tempX = WIDTH * math.random() | |
tempY = 555 * math.random() + HEIGHT | |
tempT = math.floor(7 * math.random() + 1) | |
if missiles[i].status == MISSILE_IN_FLIGHT then | |
missiles[i]:draw(day) | |
end | |
-- check to see if missiles have hit ground | |
if missiles[i].status == MISSILE_DONE then | |
houses[missiles[i].target].type = HOUSE_DESTROYED | |
sound(SOUND_EXPLODE, 111) | |
level:hit() | |
missiles[i].status = MISSILE_DESTROYED | |
elseif missiles[i].status == MISSILE_IN_FLIGHT then | |
-- check to see if missiles are destroyed | |
for s = 1, 5 do | |
if shots[s].status == SHOT_DONE then | |
if shots[s]:collision(missiles[i].x, | |
missiles[i].y) then | |
sound(SOUND_EXPLODE, 111) | |
fill(255, 220, 0, 255) | |
stroke(255, 224, 0, 255) | |
ellipse(missiles[i].x, missiles[i].y, 22,33) | |
missiles[i].status = MISSILE_DESTROYED | |
score:add(100) | |
level:hit() | |
end | |
end | |
end | |
end | |
if missiles[i].status == MISSILE_DESTROYED then | |
if level:over() then | |
if houseCount() == 0 then | |
level:gameOver() | |
else | |
level:drawOver() | |
if ElapsedTime > level.endTime + 3 then | |
sound(SOUND_PICKUP) | |
level = Level(level.number + 1) | |
startLevel() | |
end | |
end | |
elseif level:active() then | |
missiles[i]:reset(tempX, tempY, tempT) | |
level.launched = level.launched + 1 | |
end | |
end | |
end | |
-- draw the shots | |
for s = 1, 5 do | |
shots[s]:draw() | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Missile = class() | |
--constants | |
MISSILE_READY = -1 | |
MISSILE_IN_FLIGHT = 0 | |
MISSILE_DONE = 1 | |
MISSILE_DESTROED = 2 | |
function Missile:init(x, y, speed) | |
self.speed = speed | |
local t = math.floor(math.random() *7 + 1) | |
self:reset(x, y, t) | |
end | |
function Missile:reset(x, y, t) | |
self.x = x | |
self.y = y | |
-- origin position | |
self.ox = self.x | |
self.oy = self.y | |
--pick a target | |
self.target = t | |
-- set change in x per cycle | |
self.dx = (self.x - (self.target * 100 - 30)) / | |
((self.y - 100) / self.speed) | |
self.status= MISSILE_IN_FLIGHT | |
end | |
function Missile:clear() | |
-- provides an outline that makes it easier to see | |
if day == 0 then | |
stroke(0, 0, 0, 255) | |
else | |
stroke(255, 159, 0, 255) | |
end | |
strokeWidth(5) | |
line(self.ox, self.oy, self.x, self.y) | |
end | |
function Missile:draw(day) | |
--self:clear(day) | |
if self.status == MISSILE_IN_FLIGHT then | |
if self.y < 120 then | |
self.status = MISSILE_DONE | |
sprite("Small World:Explosion", self.x, self.y) | |
else | |
-- update position | |
self.x = self.x - self.dx | |
self.y = self.y - self.speed | |
if day then | |
stroke(232, 222, 6, 105) | |
else | |
stroke(0, 0, 0, 120) | |
end | |
strokeWidth(5) | |
line(self.ox, self.oy, self.x, self.y) | |
ellipse(self.x, self.y, 10) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Score = class() | |
-- this class does little but, surprise, display the score | |
function Score:init() | |
-- you can accept and set parameters here | |
self.val = 0 | |
end | |
function Score:add(x) | |
self.val = self.val + x | |
end | |
-- Draw a number | |
function drawNumber(x, y, n) | |
w = 15 | |
h = 20 | |
stroke(236, 72, 62, 255) | |
fill(234, 82, 70, 255) | |
strokeWidth(4) | |
if string.match(n, "1") then | |
line(x + (w / 2), y, x + (w / 2), y - h) | |
elseif string.match(n, "2") then | |
line(x, y, x + w, y) | |
line(x + w, y, x + w, y - (h / 2)) | |
line(x + w, y - (h / 2), x, y - (h / 2)) | |
line(x, y - (h / 2), x, y - h) | |
line(x, y - h, x + w, y - h) | |
elseif string.match(n, "3") then | |
line(x, y, x + w, y) | |
line(x + w, y, x + w, y - h) | |
line(x + w, y - h, x, y - h) | |
line(x, y - (h / 2), x + w, y - (h / 2)) | |
elseif string.match(n, "4") then | |
line(x, y, x, y - (h / 2)) | |
line(x, y - (h / 2), x + w, y - (h / 2)) | |
line(x + w, y, x + w, y - h) | |
elseif string.match(n, "5") then | |
line(x + w, y, x, y) | |
line(x, y, x, y - (h / 2)) | |
line(x, y - (h / 2), x + w, y - (h / 2)) | |
line(x + w, y - (h / 2), x + w, y - h) | |
line(x + w, y - h, x, y - h) | |
elseif string.match(n, "6") then | |
line(x + w, y, x, y) | |
line(x, y, x, y - h) | |
line(x, y - h, x + w, y - h) | |
line(x + w, y - h, x + w, y - (h / 2)) | |
line(x + w, y - (h / 2), x, y - (h / 2)) | |
elseif string.match(n, "7") then | |
line(x, y, x + w, y) | |
line(x + w, y, x + w, y - h) | |
elseif string.match(n, "8") then | |
line(x, y, x + w, y) | |
line(x + w, y, x + w, y - h) | |
line(x + w, y - h, x, y - h) | |
line(x, y - h, x, y) | |
line(x, y - (h / 2), x + w, y - (h / 2)) | |
elseif string.match(n, "9") then | |
line(x + w, y - (h / 2), x, y - (h / 2)) | |
line(x, y - (h / 2), x, y) | |
line(x, y, x + w, y) | |
line(x + w, y, x + w, y - h) | |
line(x + w, y - h, x, y - h) | |
elseif string.match(n, "0") then | |
line(x, y, x + w, y) | |
line(x + w, y, x + w, y - h) | |
line(x + w, y - h, x, y - h) | |
line(x, y - h, x, y) | |
elseif string.match(n, "x") then | |
line(x, y - (w / 3), x + w, y - (h + 1)) | |
line(x + w, y - (w / 3), x, y - (h + 1)) | |
end | |
end | |
function Score:draw() | |
l = string.len(self.val) | |
for i = 1, l do | |
drawNumber(10 + (i * 30), HEIGHT - 10, | |
string.sub(self.val, i, i)) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shot = class() | |
-- this class tracks your return fire | |
-- constants | |
SHOT_READY = -1 | |
SHOT_IN_FLIGHT = 0 | |
SHOT_DONE = 1 | |
function Shot:init(sx, sy, tx, ty, stat) | |
self.x = sx | |
self.y = sy | |
self.tx = tx | |
self.ty = ty | |
self.status = stat | |
self.size = 1 | |
self.speed = 10 | |
end | |
function Shot:load(sx, sy, tx, ty) | |
self.x = x | |
self.y = y | |
self.tx = tx | |
self.ty = ty | |
self.status = SHOT_READY | |
end | |
function Shot:launch(sx, sy, tx, ty) | |
self.status = SHOT_IN_FLIGHT | |
self.size=0 | |
self.x = sx | |
self.y = sy | |
self.tx = tx | |
self.ty = ty | |
end | |
function Shot:update() | |
if self.status == SHOT_IN_FLIGHT then | |
if self.x < self.tx then | |
self.x = self.x + self.speed | |
elseif self.x > self.tx then | |
self.x = self.x - self.speed | |
end | |
if self.y < self.ty then | |
self.y = self.y + self.speed | |
elseif self.y > self.tx then | |
self.y = self.y - self.speed | |
end | |
-- check if done | |
if math.abs(self.x - self.tx) < self.speed * 2 and | |
math.abs(self.y - self.ty) < self.speed * 2 then | |
self.status = SHOT_DONE | |
sound(SOUND_SHOOT,222) | |
end | |
end | |
return nil | |
end | |
function Shot:collision(x, y) | |
if math.abs(self.tx - x) < self.size * 3 and | |
math.abs(self.ty - y) < self.size * 2 and | |
self.size < 21 then | |
return true | |
end | |
return false | |
end | |
function Shot:draw() | |
self:update() | |
if self.status == SHOT_IN_FLIGHT then | |
fill(247, 255, 0, 255) | |
stroke(182, 179, 99, 255) | |
ellipse(self.x, self.y, 11, 11) | |
stroke(128, 130, 153, 255) | |
ellipse(self.tx, self.ty, 11, 11) | |
return nil | |
end | |
if self.status == SHOT_DONE then | |
-- do the explosion | |
self.size = self.size + 0.5 | |
strokeWidth(0) | |
fill(255, 177, 0, 255 - self.size * 11) | |
stroke(255, 179, 0, 255) | |
ellipse(self.tx, self.ty, self.size * 3, self.size * 2) | |
if self.size > 30 then | |
self:load(0,0,0,0) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment