edge 0.8.4 → 0.8.6
raw patch · 4 files changed
+281/−1 lines, 4 filesbinary-added
Files
- Resources.hs +38/−0
- Unit/Smart/STank.hs +241/−0
- edge.cabal +2/−1
- image/stank.bmp binary
Resources.hs view
@@ -15,6 +15,7 @@ import qualified Unit.Simple.Turret as Turret import qualified Unit.Smart.Tank as Tank import qualified Unit.Smart.ATank as ATank+import qualified Unit.Smart.STank as STank import qualified Unit.Smart.Death as Death import qualified Unit.Smart.Ninja as Ninja import qualified Unit.Smart.Saucer as Saucer@@ -46,6 +47,7 @@ , "nuke-1.bmp" , "nuke-2.bmp" , "nuke-3.bmp"+ , "stank.bmp" , "turret.bmp" , "tank.bmp" , "explosion-00.bmp"@@ -412,6 +414,39 @@ [ ((0.0, -1000.0), 0.0) ] }+ ,+ -- 9+ a { asteroids = asteroidGen rt wmap+ [ ((1000, -300), (-50, 100))+ , ((-1020, 1290), (120, 20))+ , ((540, -1400), (90, 70))+ ] +++ bigAsteroidGen rt wmap+ [ ((-400, -200), (40, 20))+ , ((-1300, -850), (50, -160))+ ] + , simpleUnits = turretGen rt wmap+ [ ((500.0, 650.0), 0.0, pi )+ , ((-1300.0, -650.0), 0.0, pi )+ ]+ , smartUnits = aTankGen rt wmap+ [ ((-450.0, 821.0), 0.0)+ , ((40.0, -1400.0), pi)+ , ((600.0, 90.0), 0.0)+ , ((900.0, -1200.0), pi)+ ] +++ sTankGen rt wmap+ [ ((450.0, -721.0), 0.0)+ , ((200.0, 1450.0), pi)+ , ((-600.0, 190.0), 0.0)+ , ((700.0, -1000.0), pi)+ ]+ , unitProjectiles = mineGen rt wmap+ [ (500.0, 1000.0)+ , (-900.0, 700.0)+ , (1300.0, -1400.0)+ ]+ } ] let addItems a = do it1 <- randomItemType it2 <- randomItemType@@ -452,6 +487,9 @@ aTankGen rt wmap = map (\(x, y) -> SmartUnit (ATank.new rt wmap (wrappoint wmap x) y))++sTankGen rt wmap =+ map (\(x, y) -> SmartUnit (STank.new rt wmap (wrappoint wmap x) y)) mineGen rt wmap = map (\x -> Projectile (Mine.new rt wmap (wrappoint wmap x)))
+ Unit/Smart/STank.hs view
@@ -0,0 +1,241 @@+module Unit.Smart.STank ( STank(..)+ , new+ ) where++import Data.WrapAround+import Animation+import Graphics.Gloss.Data.Picture+import Graphics.Gloss.Data.Color+import GHC.Float+import Trigonometry+import ResourceTracker+import Updating+import qualified Moving as M+import Combat+import qualified Projectile.BulletMII as P.BulletMII+import AfterEffect+import qualified AfterEffect.SimpleExplosion as SimpleExplosion+import Data.Maybe+import Universe hiding (wrapMap, resourceTracker)+import qualified Universe as U+import Sound.ALUT+import Common++radialVelocity = pi/4 -- radians per second++maxVelocityMag = 100++kamikazeDamage = 20.0++maxIntegrity = 6++accelerationRate = 60++collisionRadiusC = 45++shotDelay = 2.0++data STank = STank { angle :: Angle+ , velocity :: Velocity+ , center :: WrapPoint+ , idealTargetLocation :: Maybe WrapPoint+ , wrapMap :: WrapMap+ , launchTube :: [Projectile]+ , sinceLastShot :: Time+ , integrity :: Double+ , vision :: Maybe Arena+ , resourceTracker :: ResourceTracker++ -- Sound+ , queueShotSound :: Bool+ , shotSoundSource :: Maybe Source+ }++instance Audible STank where++ processAudio self lcenter =+ do self' <- if isNothing (shotSoundSource self)+ then initializeShotSoundSource self+ else return self+ if not (queueShotSound self)+ then return self'+ else do let (x, y) = vectorRelation+ (wrapMap self)+ (lcenter)+ (center self)+ let s = fromJust $ shotSoundSource self+ sourcePosition s $= (Vertex3 (double2Float x)+ (double2Float (-y))+ 0)+ play [s]+ return self' { queueShotSound = False }++ terminateAudio self =+ if isNothing (shotSoundSource self)+ then return self+ else do stop [fromJust (shotSoundSource self)]+ return self++initializeShotSoundSource self =+ do [source] <- genObjectNames 1+ buffer source $= getSound (resourceTracker self) "energy-shot-02.wav"+ sourceRelative source $= Listener+ referenceDistance source $= audioReferenceDistance+ rolloffFactor source $= audioRolloffFactor+ return self { shotSoundSource = Just source }++new :: ResourceTracker+ -> WrapMap+ -> WrapPoint+ -> Angle+ -> STank+new rt wmap center' angle' =+ STank { center = center'+ , angle = angle'+ , idealTargetLocation = Nothing+ , velocity = (0.0, 0.0)+ , wrapMap = wmap+ , launchTube = []+ , sinceLastShot = 0.0+ , integrity = maxIntegrity+ , vision = Nothing+ , resourceTracker = rt++ , queueShotSound = False+ , shotSoundSource = Nothing+ }++instance Observant STank where++ updateVision self arena = self { vision = Just arena }++updateAngle t self+ = case vision self of+ Nothing -> self+ Just arena -> if isNothing (lance arena)+ then self+ else let sDir = vectorDirection (velocity self) in+ let tDir = vectorDirection+ (vectorRelation+ (U.wrapMap arena)+ (center self)+ (M.center (fromJust (lance arena)))) in+ let adj+ | tDir - sDir > pi / 6 = radialVelocity * t+ | tDir -sDir < (-pi) / 6 = (-radialVelocity) * t+ | otherwise = 0.0 in+ self { angle = angle self + adj }++updateVelocity :: Time -> STank -> STank+updateVelocity t self =+ self { velocity = M.calcNewVelocity+ (velocity self)+ accelerationRate+ (angle self)+ maxVelocityMag+ t + }++instance Animation STank where+ image self _ = Rotate (radToDeg+ (double2Float+ (angle self)) * (-1) - 90)+ pic+ where pic = fromMaybe+ (Scale 0.20 0.20+ (Color white+ (Text "Error! Missing image!")))+ (getImage rt "stank.bmp")+ rt = resourceTracker self++instance M.Locatable STank where+ center = center++instance M.Moving STank where+ velocity = velocity++instance M.Colliding STank where+ collisionRadius _ = collisionRadiusC++instance InternallyUpdating STank where++ preUpdate self t = (updateFiringInformation t+ . updateIdealTargetLocation t+ . updateVelocity t+ . updateAngle t) self++ postUpdate self t =+ let center' = fromMaybe (center self) (idealTargetLocation self) in+ self { center = center'+ , idealTargetLocation = Nothing+ }++updateFiringInformation t self =+ let sinceLastShot' = sinceLastShot self + t in+ if sinceLastShot' >= shotDelay+ then self { sinceLastShot = 0.0+ , launchTube = projectile1 + : (projectile2+ : (projectile3+ : launchTube self))+ , queueShotSound = True+ }+ else self { sinceLastShot = sinceLastShot' }+ where projectile1 = Projectile+ (P.BulletMII.new+ (wrapMap self)+ pAngle+ (center self)+ (velocity self))+ projectile2 = Projectile+ (P.BulletMII.new+ (wrapMap self)+ (pAngle + pi / 8)+ (center self)+ (velocity self))+ projectile3 = Projectile+ (P.BulletMII.new+ (wrapMap self)+ (pAngle - pi / 8)+ (center self)+ (velocity self))+ pAngle = case vision self of+ Nothing -> angle self+ Just arena ->+ case lance arena of+ Nothing -> angle self+ Just l -> vectorDirection+ (vectorRelation+ (U.wrapMap arena)+ (center self)+ (M.center l))++updateIdealTargetLocation :: Time -> STank -> STank+updateIdealTargetLocation t self =+ self { idealTargetLocation = Just (M.idealNewLocation (wrapMap self)+ (center self)+ (velocity self)+ t)+ }++instance Launcher STank where++ deployProjectiles self = (launchTube self, self { launchTube = [] })++instance Transient STank where++ expired' self = if integrity self > 0.0+ then Nothing+ else Just [aeffect]+ where aeffect = AfterEffect (SimpleExplosion.new (resourceTracker self)+ (wrapMap self)+ (center self)+ (velocity self))++instance Damageable STank where++ inflictDamage self d = self { integrity = max 0.0 (integrity self - d) }++instance Damaging STank where++ damageEnergy self = kamikazeDamage
edge.cabal view
@@ -7,7 +7,7 @@ -- The package version. See the Haskell package versioning policy -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for -- standards guiding when and how versions should be incremented.-Version: 0.8.4+Version: 0.8.6 -- A short (one-line) description of the package. Synopsis: Top view space combat arcade game@@ -105,6 +105,7 @@ , Unit.Simple.Turret , Unit.Smart.Tank , Unit.Smart.ATank+ , Unit.Smart.STank , Unit.Smart.Death , Unit.Smart.Ninja , Unit.Smart.Saucer
+ image/stank.bmp view
binary file changed (absent → 34714 bytes)