Skip to content

Commit

Permalink
Progress towards highlights working
Browse files Browse the repository at this point in the history
  • Loading branch information
autismuk committed Nov 4, 2014
1 parent 876bf6a commit 1f17553
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 37 deletions.
41 changes: 41 additions & 0 deletions source/gfx/ball.lua
@@ -0,0 +1,41 @@
--- ************************************************************************************************************************************************************************
---
--- Name : ball.lua
--- Purpose : Ball Graphic Object
--- Updated: 4 November 2014
--- Author: Paul Robson (paul@robsons.org.uk)
--- License: Copyright Paul Robson (c) 2014+
---
--- ************************************************************************************************************************************************************************

local BallGraphic = Framework:createClass("gfx.ball")

function BallGraphic:constructor(info)
self.m_ballShadow = display.newCircle(0,0,12)
self.m_ball = display.newImage("images/ball.png")
self.m_ball.width,self.m_ball.height = self.m_ballShadow.width,self.m_ballShadow.height
self.m_ballShadow:setFillColor(0,0,0,0.3)
end

function BallGraphic:destructor()
salf.m_ball:removeSelf()
end

function BallGraphic:move(x,y)
self.m_ballShadow.x,self.m_ballShadow.y = x+5,y-5
self.m_ball.x,self.m_ball.y = x,y
self.m_ball.rotation = x*34-y*37
end

function BallGraphic:setRotation(rot)
end

--- ************************************************************************************************************************************************************************
--[[
Date Version Notes
---- ------- -----
4-Nov-14 0.1 Initial version of file
--]]
--- ************************************************************************************************************************************************************************
19 changes: 12 additions & 7 deletions source/gfx/player.lua
Expand Up @@ -29,15 +29,15 @@ function PlayerGraphic:constructor(info)
self:move(info.x or 0,info.y or 0) -- move it.
self:showMarker(info.marker or false) -- show the marker.
if info.shadow == false then self:showShadow(false) end -- show shadow, defaults to true e.g. must supply false.
self:setSkinTone(info.skin or 40) -- skin colour a light brown.
self:setSkinTone(info.skin) -- skin colour a light brown.
self:setStrip(info.shirt or "#FFFF00", info.shorts or "#008000") -- Norwich City strip (Yellow/Green)
self:setHair(info.hair or "#663300") -- Hair colour (brown)
self:setRotation(info.direction or 0) -- set the rotation
self:tag("player") -- these are tagged
end

function PlayerGraphic:destructor()
self.m_group:removeAll() self.m_group = nil self.m_gfx = nil -- remove all references to graphics objects.
self.m_group:removeSelf() self.m_group = nil self.m_gfx = nil -- remove all references and graphics objects.
end

--// Move the player to position x/y on the physical screen.
Expand Down Expand Up @@ -66,7 +66,7 @@ function PlayerGraphic:setRotation(angle)
self.m_gfx.shadow.rotation = -45-angle -- the shadow does not rotate
self.m_gfx.marker.rotation = -angle -- the marker does not rotate
if not self.m_isCameraAtBottom then angle = angle + 180 end -- if camera at top, reverse it
local event = math.sin(math.rad(angle)) * 12 -- work out the lean given the camera angle
local event = math.sin(math.rad(angle)) * 15 -- work out the lean given the camera angle
self:alignBody(event) -- and lean the player only
end

Expand Down Expand Up @@ -152,14 +152,19 @@ function PlayerGraphic:fill(object,rgb,isLine)
end

--// Convert string RGB
--// @rgb [rgb] table or #RRGGBB as string.
--// @rgb [rgb] table or #RRGGBB or #RGB as string.
--// @return [table] RGB table.

function PlayerGraphic:convert(rgb)
if type(rgb) == "string" then -- process strings.
assert(rgb:sub(1,1) == "#" and #rgb == 7) -- basic checks.
rgb = { tonumber(rgb:sub(2,3),16)/255, -- do the conversion.
tonumber(rgb:sub(4,5),16)/255,tonumber(rgb:sub(6,7),16)/255}
assert(rgb:sub(1,1) == "#" and (#rgb == 7 or #rgb == 4)) -- basic checks.
if #rgb == 7 then
rgb = { tonumber(rgb:sub(2,3),16)/255, -- do the conversion.
tonumber(rgb:sub(4,5),16)/255,tonumber(rgb:sub(6,7),16)/255}
else
rgb = { tonumber(rgb:sub(2,2),16)/15, -- do the conversion.
tonumber(rgb:sub(3,3),16)/15,tonumber(rgb:sub(4,4),16)/15}
end
end
return rgb
end
Expand Down
128 changes: 128 additions & 0 deletions source/highlights/manager.lua
@@ -0,0 +1,128 @@
--- ************************************************************************************************************************************************************************
---
--- Name : manager.lua
--- Purpose : Manages the players during the game, e.g. drives the highlights
--- Updated: 4 November 2014
--- Author: Paul Robson (paul@robsons.org.uk)
--- License: Copyright Paul Robson (c) 2014+
---
--- ************************************************************************************************************************************************************************

require("highlights.members")


local MapClass = Framework:createClass("gfx.mapper")

function MapClass:constructor() end function MapClass:destructor() end

function MapClass:map(x,y)
x = ((x or 0)*0.93 + 512) / 1024 * display.contentWidth -- calculate actual physical position
y = (y or 0)/1024 * (display.contentHeight-140) + 140
return x,y
end

function MapClass:mapRotate(r)
return r
end

local HighlightsManager = Framework:createClass("highlights.manager")

function HighlightsManager:constructor(info)
self.m_mapper = Framework:new("gfx.mapper") -- helper object maps logical -> physical
self.m_goalWidth = 140 -- goal width in logical units.
self.m_pitchGroup = display.newGroup()
self:createBackground()

self.m_attackers = {} self.m_defenders = {} self.m_objects = {} -- lists of attackers, defenders and objects

local descr = { camera = "bottom", mapper = self.m_mapper, x = 0,y = 100, direction = 90 } -- set up, initially, for the ball start

self.m_ball = Framework:new("highlights.objects.ball",descr) -- create ball and goalkeeper
descr.y = 20 self.m_goalKeeper = Framework:new("highlights.objects.goalkeeper",descr)

self.m_objects[#self.m_objects+1] = self.m_goalKeeper -- add to object list.
self.m_objects[#self.m_objects+1] = self.m_ball

for i = 1,3 do -- create three defenders.
descr.x = (i-2)*370-120+math.random()*240 -- position.
descr.y = 150+math.random()*350
self.m_defenders[i] = Framework:new("highlights.objects.defender",descr) -- create defender
self.m_objects[#self.m_objects+1] = self.m_defenders[i] -- add to general objects list.
end

for i = 1,3 do -- create three attackers.
descr.x = (i-2)*370-120+math.random()*240 -- position.
descr.y = 650+math.random()*350
descr.direction = -90
if i == 2 then -- create either a centre forward or an attacker
self.m_attackers[i] = Framework:new("highlights.objects.centreforward",descr)
else
self.m_attackers[i] = Framework:new("highlights.objects.attacker",descr) -- add to general objects list.
end
self.m_objects[#self.m_objects+1] = self.m_attackers[i]
end

self.m_lastPlayerWithBall = nil self.m_playerWithBall = nil -- ball not held by any player
self:giveBallToPlayer(self.m_attackers[math.random(1,#self.m_attackers)]) -- give it to an attacker.
end

function HighlightsManager:giveBallToPlayer(player)
if self.m_lastPlayerWithBall ~= nil then self.m_lastPlayerWithBall:setHasBall(false) end -- take it away from the last player
if player ~= nil then player:setHasBall(true) end -- give it to the new player.
self.m_lastPlayerWithBall = self.m_playerWithBall -- update current, last.
self.m_playerWithBall = player
end

function HighlightsManager:destructor()
self.m_mapper:delete() self.m_mapper = nil -- delete mapper
for _,ref in ipairs(self.m_objects) do ref:delete() end -- delete all known objects
self.m_objects = nil self.m_attackers = nil self.m_defenders = nil self.m_goalKeeper = nil -- nil out all references.
self.m_ball = nil
self.m_pitchGroup:removeSelf() self.m_pitchGroup = nil -- remove background
end

function HighlightsManager:start()
self:tag("enterFrame")
end

function HighlightsManager:onEnterFrame(deltaTime)
for _,ref in ipairs(self.m_objects) do -- tick all objects.
ref:tick(deltaTime)
end
if self.m_playerWithBall ~= nil then -- move the ball to the player.
local x,y = self.m_playerWithBall:get() -- get position and direction
local dir = math.rad(self.m_playerWithBall:getDirection())
local offset = 50
self.m_ball:move(x+offset*math.cos(dir),y+offset*math.sin(dir))
end
end

function HighlightsManager:createBackground()
local x1,x2,y x1,y = self.m_mapper:map(-512,0) x2,y = self.m_mapper:map(512,0) -- pitch lines
local r = display.newRect(self.m_pitchGroup,0,0,960,640) r.anchorX,r.anchorY = 0,0 r:setFillColor(0,0.4,0)
display.newLine(self.m_pitchGroup,x1,y,x2,y).strokeWidth = 4
display.newLine(self.m_pitchGroup,x1,y,x1,640).strokeWidth = 4
display.newLine(self.m_pitchGroup,x2,y,x2,640).strokeWidth = 4
r = display.newImage(self.m_pitchGroup,"images/goal.png",0,0) -- get goal
r.anchorY = 1 r.x,r.y = self.m_mapper:map(0,0)
x1,y = self.m_mapper:map(-self.m_goalWidth,0) -- work out how big it is
x2,y = self.m_mapper:map(self.m_goalWidth,0)
local scale = (x2-x1) / r.width r.xScale,r.yScale = scale,scale -- scale goal graphic accordingly.
local offset = r.height * scale * display.contentHeight / display.contentWidth -- goal shadow
local shadow = display.newPolygon(120,120,{ offset,0, 0,r.height*scale, r.width*scale,r.height*scale, r.width*scale+offset,0 })
shadow:setFillColor(0,0,0,0.3)
shadow.anchorY = 1 shadow.x,shadow.y = r.x + offset/2,r.y r:toFront()
end

--- ************************************************************************************************************************************************************************
--[[
Date Version Notes
---- ------- -----
4-Nov-14 0.1 Initial version of file
--]]
--- ************************************************************************************************************************************************************************
77 changes: 63 additions & 14 deletions source/highlights/members.lua
Expand Up @@ -8,14 +8,19 @@
---
--- ************************************************************************************************************************************************************************

require("gfx.player")
require("gfx.ball")

--- ************************************************************************************************************************************************************************
--// Abstract Superclass for all displayable objects
--- ************************************************************************************************************************************************************************

local MoveableGameObject = Framework:createClass("highlights.objects.base")

function MoveableGameObject:constructor(info)
self.m_mapper = info.mapper assert(self.m_mapper ~= nil) -- save logical to physical mapper.
self.m_distanceToTravel = 0 -- number of logical units to travel.
self.m_hasBall = false -- does not have ball.
self.m_direction = 90 -- current direction.
self.m_displayObject = self:createGameObject(info) -- create a game object which implements move(),rotate()
-- ** NOT A CORONA DISPLAY OBJECT **
Expand All @@ -24,7 +29,9 @@ function MoveableGameObject:constructor(info)
end

function MoveableGameObject:destructor()
self.m_displayObject = nil -- remove reference to display object
self.m_displayObject:delete()
self.m_displayObject = nil -- remove reference to display object and mapper
self.m_mapper = nil
end

function MoveableGameObject:createGameObject(info) -- this *must* be sub classed.
Expand All @@ -50,9 +57,21 @@ function MoveableGameObject:moveTo(x,y)
local distance = math.sqrt((x-self.m_xLogical)*(x-self.m_xLogical)+ -- work out distance to move.
(y-self.m_yLogical)*(y-self.m_yLogical))
self:rotate(dir) -- set the graphic rotation.
self.m_distanceToTravel = distance self.m_direction = math.rad(dir) -- set the travelling distance and direction.
self.m_distanceToTravel = distance self.m_direction = dir -- set the travelling distance and direction.
end

function MoveableGameObject:get()
return self.m_xLogical,self.m_yLogical
end

function MoveableGameObject:getDirection()
return self.m_direction
end

function MoveableGameObject:setHasBall(hasBall)
self.m_hasBall = hasBall
end

function MoveableGameObject:tick(deltaTime)
if self.m_distanceToTravel <= 0 or self:isRethinkRequired() then -- reached end, or is a rethink required
self:rethink() -- decide what to do next.
Expand All @@ -61,20 +80,19 @@ function MoveableGameObject:tick(deltaTime)
if self.m_distanceToTravel <= 0 then return end -- doing nothing.
local dist = math.min(deltaTime * self:getSpeed() * 1000,self.m_distanceToTravel) -- how far to go.
self.m_distanceToTravel = self.m_distanceToTravel - dist -- reduce distance to go.
self:move(self.m_xLogical+dist*math.cos(self.m_direction),
self.m_yLogical+dist*math.sin(self.m_direction))
self:move(self.m_xLogical+dist*math.cos(math.rad(self.m_direction)),
self.m_yLogical+dist*math.sin(math.rad(self.m_direction)))
end

function MoveableGameObject:move(x,y)
self.m_xLogical,self.m_yLogical = x,y -- save logical position
x = ((x or 0)*0.9 + 512) / 1024 * display.contentWidth -- calculate actual physical position
y = (y or 0)*0.57 + 40
x,y = self.m_mapper:map(x,y)
self.m_displayObject:move(x,y) -- and draw it
end

function MoveableGameObject:rotate(angle)
self.m_direction = angle or self.m_direction -- default is original value
self.m_displayObject:setRotation(self.m_direction) -- update direction.
self.m_displayObject:setRotation(self.m_mapper:mapRotate(self.m_direction)) -- update direction.
end

--- ************************************************************************************************************************************************************************
Expand All @@ -84,28 +102,59 @@ end
local Player,SuperClass = Framework:createClass("highlights.objects.player","highlights.objects.base")

function Player:createGameObject(info)
local displayObj = Framework:new("gfx.player",{ camera = info.camera }) -- create a player display object
displayObj:setRadius(32) -- set its size
local colors = self:getColourScheme(info)
local displayObj = Framework:new("gfx.player",{ camera = info.camera, -- create a player display object
shirt= colors.shirt, shorts = colors.shorts, colors.hair, skin = colors.skin })
displayObj:setRadius(24) -- set its size
return displayObj -- and return it.
end

function Player:getColourScheme(info)
return { shirt = "#FF0000", shorts = "#FFFFFF", hair = "#000000", skin = 80 }
end

--- ************************************************************************************************************************************************************************
--- ************************************************************************************************************************************************************************

local Goalkeeper,SuperClass = Framework:createClass("highlights.objects.goalkeeper","highlights.objects.player")

function Goalkeeper:getColourScheme(info)
local scheme = SuperClass.getColourScheme(self,info)
scheme.shirt = "#00CC00" scheme.shorts = "#00EE00"
return scheme
end

--- ************************************************************************************************************************************************************************
--- ************************************************************************************************************************************************************************

local Attacker,SuperClass = Framework:createClass("highlights.objects.attacker","highlights.objects.player")

--- ************************************************************************************************************************************************************************
--- ************************************************************************************************************************************************************************

local CentreForward,SuperClass = Framework:createClass("highlights.objects.centreforward","highlights.objects.attacker")

--- ************************************************************************************************************************************************************************
--- ************************************************************************************************************************************************************************

local Defender,SuperClass = Framework:createClass("highlights.objects.defender","highlights.objects.player")

function Defender:getColourScheme(info)
local scheme = SuperClass.getColourScheme(self,info)
scheme.shirt = "#00F" scheme.shorts = "#FFFFFF"
return scheme
end

--- ************************************************************************************************************************************************************************
--- ************************************************************************************************************************************************************************

local Ball,SuperClass = Framework:createClass("highlights.objects.ball","highlights.objects.base")

--[[
function Ball:createGameObject(info)
return Framework:new("gfx.ball") -- and return it.
end

shirt/shorts/skin code on initialisation.
abstract out logical->physical
then start building up highlights object.

--]]

--- ************************************************************************************************************************************************************************
--[[
Expand Down
Binary file added source/images/ball.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 1f17553

Please sign in to comment.