Graviton 0.10 Released

Miscellaneous Forums/Blitz Showcase/Graviton 0.10 Released

Fight your way through 11 levels in this retro style 2D in 3D space shooter. Created with B3D, 95% complete, 95% to do.


Download Graviton v0.11 (4.4MB zip)




Features :
* 11 Levels (so far)
* Enemy bases with turrets, saucers etc..
* Many asteroids :)
* Gravity Vortex
* Powerups include extra firepower, smart bombs, shield replenish
* Large scrolling play area
* Sound fx
* Lots of particle fx

Hint - press a number key on the title page to go straight to a level for now (until I get level selection in).

http://minimono.net

Nice work. I enjoyed this. Only had a fairly quick play though, - got to level 4, I think.

I found the controls a bit fiddly and the nature of the vortex gravity etc. made me feel like I wasn't in control alot of the time.

You need to disable pause when entering a highscore, BTW.

Personally, I'd prefer a more pointy-looking ship, rather than the round one. Makes it visually easy to gauge which direction you're pointing.

Overall, a polished and enjoyable game with lots of potential. Well done.

P.S. the smart bomb particle effect looks mighty familiar to me. ;)

I like this a lot. Very polished overall - great intro screens.

To echo some of 10ps points-
- Would be nice if some levels dont have the vortex, though it does add a different gameplay element
-Main ship - definitely a bit more pointy - it looks nice when it goes 3d at the end of a level, but viewed from above it looks really naff in comparison to the rest of your gfx.

Keep up the good work.

Thanks guys. Glad you liked it.

@big10p - High score bugette fixed now. Well spotted. The smart bomb effect did indeed originate from your code archive entry which turned out to be not so pointless after all :) I hope to contribute a lot more to the archives myself as they are imho indispensable and one of the best resources for learning from.

Agreed on the controls difficulty factor. I've been testing it so long that I've become pretty skilled at flying around the vortex (try orbiting rather than going in at 90 degrees) but it's easy to forget how awkward it is to start with. I'm thinking of maybe adding a new 'anti-grav' power up that negates the vortex effect on the ship.

Also agreed on the ship model. A more pointy ship would indeed be nicer. I'll have to try & improve my 3D modelling skills unless anyone knows of a good resource for low poly spaceships :)

Again thanks for the feedback. Much appreciated.

This is a very nice game, great gameplay.

DUDE! I forgot I downloaded it a couple days ago and just now tried it. DAMN FUN! Very well done. Super polished. Maybe some tweaking on the game play and you got a winner!!! I dig the effects of the particles. Takes me back!

Have just uploaded a new version 0.11

(Use the link in the first post)

* New pointy ship graphic ! (model courtesy of http://www.psionic3d.co.uk)
* Tweaked start position on the first few levels to make it easier for new players
* Powerups now get left behind when you die so you can pick them up again (if you get there in time)
* Powerups can now be collected at level end
* Radar impoved. enemy/powerup blip size increased a tad
* New anti gravity powerup to help new players get used to the control system.
* Added attract mode
* Added experimental mouse control + left shift & ctrl can be used for thrust - caveat - not tried it on anything other than my laptop trackpad yet

Nice start. Quite fun. Just a couple of suggestions.

When the asteroids are blown up it would be nice to see the fragments move off in different directions rather than continue on in generally the same direction as before.

The fire rate of the ship seems a bit random. Sometimes very fast sometimes slow?? Not aware that I picked up any sort of power up to boost or retard fire rate.

Need some visual indication of thrust in other directions. i.e. reverse and rotational IMO

Great job! Man I start working on a space shooter a few months ago and now people are coming out with them left and right ... and they're all better! What am I to do? Haha!

Geehawk, the fire rate should be pretty constant unless it's on a go slow for some reason. Sure I removed the retard fire rate powerup ;) Could be that sometimes stuff takes longer than a whole frame to process and given that I use vsync that would make it skip a bit. What sort of system spec have you got ? I ditched the b3d collision system and wrote my own which is a little CPU intensive so may have to look at optimizing it in C.

I'll try and enhance the asteroid explosions and add more thruster gfx amongst other things for the next release.

Thanks for the suggestions.

Fun!!

I've been playing this a bunch. A great WIP game!

Some constructive feedback:

1. If you hold down while the ship is flying toward the screen at the end of a level, you hear the thruster.

2. If you die right before the level is completed, (e.g. the last enemy smashes into an asteroid,) your ship will reappear after the normal death delay and spin in place (while you'd normally be watching the ship fly at the camera.)

3. The anti-gravity powerup is crippling to learning how to play with gravity. Maybe earlier levels could have gravity that doesn't affect the player's ship - or later levels could have gravity that isn't negated by the anti-gravity powerup.

4. Your particle effects system needs some limits - it's possible to slow down the game considerably by causing a lot of simultaneous explosions.

5. Perhaps a gravity indicator to show which direction your ship is being pulled in and how quickly? On level 11, it's suicidal to get in a dogfight anywhere near the heavy moons unless you know the level very well and glue an eye to your radar.

6. Consider removing the ability to choose when to launch. Level 11 becomes much less evil if you launch as soon as possible - this gives new players a big (and counter-intuitive) disadvantage.

7. Future levels may benefit from infinitely respawning enemies. It's fun to attack an installation while fending off waves of enemies, but the challenge can be avoided by waiting around for everything to spawn and killing it first.

8. Harder enemies please! Or perhaps their accuracy could increase as the levels progress?

Some stuff from me:
+ Make higher screen resolutions possibe (better overview)
+ Add an icon to the exe / upx it

Thanks. All very good points.

Octothorpe,

1. Well spotted (or heard). Will fix that.
2. That ones easy to fix as well.
3. Yeah, anti-gravity was introduced as an experiment to try & make it easier for beginners to get used to the control system. Still not sure what the best way to deal with the learning curve is but I'll try out your idea.
4. The particle effect has an upper limit of 3000 and I'd be surprised if that's the cause of the slowdown tbh . My prime suspect would be my sphere 2 sphere collision system as the number of entitydistance() calls per frame can be quite large. If it slows down on level 11 that's probably it. What's your CPU speed ?
5. That's a nice idea. I may try something like making the exhaust trail drift towards the vortex to give you a visual indication.
6. I see your point although I wouldn't want to force the player to sit through the level overview if they didn't want to . Maybe if I try making the launch ship less vulnerable that might work. Certainly should make it so there's no disadvantage to waiting to launch.
7. Yes. Maybe enemy generator enemies ;-) Would help to keep the pace of the game a bit more hectic as well as it can seem sluggish sometimes.
8. Lots more enemies planned. Was thinking about letting the enemies pick up and use some weapons like the threeway or seekers against you.

Grisu,

I'm looking at making the camera dynamically zoom out a little to give a better playing field overview but need to make sure it works and doesn't become an annoyance. Problem with supporting higher resolutions is that the pixel effects get too small to see.
Not heard of UPX before. Will check it out.

Again, thanks everyone for the detailed feedback & useful ideas.

The particle effect has an upper limit of 3000


Enter debug mode, then repeatedly hit Z and Space as quickly as you possibly can. Doesn't take me long to get down to 1 FPS.

1.6GHz P4, .5GB RAM

I've gotten slowdown without cheating by detonating a carefully positioned bomb by the mothership and wiping out most of the turrets on it at once.

My prime suspect would be my sphere 2 sphere collision system


Since the game is essentially 2d, you could try a 2d distance check (and don't bother with SQR, just test against the squared collision radii of your objects added together.) Might help?

Maybe if I try making the launch ship less vulnerable that might work.


If you mean placing it away from the paths of the minelayers, then I agree.

Oh I see what you mean. Yes, it's the smartbomb explosion causing the slowdown. Will take a look at optimizing that.

Ah, the launch position on level 11 is indeed a bit mean. I'll fix that. What I actually meant was that if you wait too long on level 11, all the turrets gather around and start doing damage before you're even launched which is just not fair.

I did initially write the collision system to use sqr(x*x+y*y) for distance thinking that it would be faster than entitydistance() because I'm only using 2 axis but was surprised to find the latter was so much faster. Much later I realised that you didn't have to even get the square root so with renewed enthusiam I went about reverting to calculating my own distance again only to find out that it was still much slower than entitydistance(). Still, I'm sure it can be sped up further without having to revert to C.

Here's my collision module...

Save this as Collisions2D.bb

; ---------------------------------------------------------------

; Collisions2D.bb

; (Very) Simple sphere to sphere collision detection module

;

; Look at example code for an idea of how to use it.

; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; Collision types
; Dictates which EntityType combinations will be checked as per the
; collisions table Blitz3D manages itself.
; ---------------------------------------------------------------------------

Dim Collisions2Dsrctgt(64,64)
Dim Collisions2Dsrc(64)

; ---------------------------------------------------------------------------
; Collision instance
; One of these must exist for each entity that needs to be checked for collisions.
; Note that if you delete your entity and want to stop collision checks
; happening for it you *must* also delete the corresponding collision type instance.
; The example shows you a good way of doing this.
; ---------------------------------------------------------------------------

Type Collision

    ; collision entity information

    Field srcEntity  ; the entity to check collisions for
    Field srcRadius# ; the radius - equiv of EntityRadius
    Field sType      ; the entity type - equiv of EntityType

    ; collision result information

    Field hasCollided    ; boolean indicates whether a collision has taken place or not for the entity
    Field cEntity        ; collided with entity
    Field cNx#,cNy#,cNz# ; collision Normals

End Type


; ------------------------------------------------------
; Enable a valid entity type combo
; -------------------------------------------------------

Function setCollisionTypes(srcType,tgtType)

    Collisions2Dsrctgt(srcType,tgtType) = True
    Collisions2Dsrc(srcType) = True
    ;DebugLog "collision type added between types " + srcType + " and " + tgtType

End Function

; -----------------------------------------------------------------------
; Add a entity to the collision system
; Collision detection information is passed back via the Type instance.
; -----------------------------------------------------------------------

Function addCollisionEntity.Collision(entity,radius#)

    c.Collision = New Collision
    c\srcEntity = entity
    c\srcRadius = radius
    c\sType = GetEntityType(entity)
    c\hasCollided = False
    ;DebugLog "collision instance added for entity " + c\srcEntity + " type " + c\sType
    Return c

End Function

; -------------------------------------------------------------
; Perform collision detection between valid type combinations
; This method should be called once per updateWorld.
; -------------------------------------------------------------

Function updateCollisions()

    ;count = 0

    For s.Collision = Each Collision

        s\hasCollided = False

        If Collisions2Dsrc(s\sType)

            For t.Collision = Each Collision

                If Collisions2Dsrctgt(s\sType,t\sType)
                    If s\srcEntity <> t\srcEntity
                        ;count = count + 1
                        ;dx# = (EntityX(s\srcEntity,True) - EntityX(t\srcEntity,True))
                        ;dz# = (EntityZ(s\srcEntity,True) - EntityZ(t\srcEntity,True))
                        ;dsq# = dx*dx + dz*dz
                        d# = EntityDistance(s\srcEntity,t\srcEntity) ; if an error occurs here it's because you haven't deleted
                                                                     ; the collision instance associated with one of these entities !
                        If d# - s\srcRadius - t\srcRadius < 0
                        ; If dsq < (s\srcRadius*s\srcRadius+t\srcRadius*t\srcRadius)
                            ; collision has occurred !
                            s\hasCollided = True
                            s\cEntity = t\srcEntity
                         ;   d# = Sqr(dsq)
                            If d# = 0 d# = .00001 ; prevent division by zero
                            ; normalize collision vector
                          ;  s\cNx = dx / d#
                          ;  s\cNz = dz / d#
                            s\cNx = (EntityX(s\srcEntity,True) - EntityX(t\srcEntity,True)) / d#
                            s\cNz = (EntityZ(s\srcEntity,True) - EntityZ(t\srcEntity,True)) / d#
                            ;DebugLog "collision between type " + s\sType + " " + s\srcEntity + " and " + t\sType + " " + s\cEntity

                        End If
                    End If
                End If
            Next
        End If
    Next

    ;DebugLog count +" collision checks performed"

End Function

; ====================================================================================================================================


And a example program using it :

; -------------------------------
; collision library example usage
; -------------------------------

Include "Collisions2D.bb"

.define

Graphics3D 800,600

Global collisionResponseMode = 1
Global thingCount

; collision types
Const TYPE_THING     = 1

Type Thing

    Field entity
    Field xspeed#,yspeed#
    Field hp
    Field collisionInfo.Collision

End Type

.setup

; -----------------------------------------------------------
; Enable collisions between entity types.
; Same as using the Blitz3D Collisions <type>,<type> command
; but no collision type or response needed as we handle that
; ourselves.
; -----------------------------------------------------------
setCollisionTypes(TYPE_THING,TYPE_THING)

SetBuffer BackBuffer()
Global world = CreatePivot()
Global camera_target = CreatePivot(world)
Global camera = CreateCamera(world)
cameray# = -16

createThings(333)

.mainloop

While Not KeyHit(1)

    updateThings()
    If thingCount < 64 createThings(200)

    ;TurnEntity blurclear,1,0,0
    ; ----------------------
    ; Perform collision checks
    ; ----------------------
    time = MilliSecs()
    updateCollisions()
    time = MilliSecs()-time

    PositionEntity camera,0,cameray,0
    PointEntity camera,camera_target

    UpdateWorld()
    RenderWorld()
    Color 255,255,0
    modeStr$ = ""
    Select collisionResponseMode
        Case 0 modeStr = "none"
        Case 1 modeStr = "soft"
        Case 2 modeStr = "rigid"
    End Select
    Text 0,0,thingCount+" things processed in "+time+"ms"
    Text 0,16,"Press [SPACE] to cycle Collision Response Mode : " + modeStr

    Flip

    If KeyHit(57) ; space
        collisionResponseMode = (collisionResponseMode + 1) Mod 3
    End If

Wend

End



; ------------------------------------------------------------------------------------------------------------------------------------

Function createThings(amount=64)

    For i = 1 To amount

        x# = Rand(-16,16)
        y# = Rand(-12,12)
        xspeed# = Rnd(-.08,.08)
        yspeed# = Rnd(-.08,.08)
        size# = Rnd(.1,.5)
        createThing(x,y,xspeed,yspeed,size)

    Next

End Function

; ------------------------------------------------------------------------------------------------------------------------------------

Function createThing(x#,y#,xspeed#,yspeed#,radius#)

    a.Thing = New Thing

    a\entity = CreateSphere(6)
    EntityColor a\entity,255,255,0
    EntityBlend a\entity,3
    EntityAlpha a\entity,.7
    PositionEntity a\entity,x,0,y
    ScaleEntity a\entity,radius,radius,radius
    EntityType a\entity,TYPE_THING ; make sure type is setup *beforehand*
    ; --------------------------------------------------------
    ; Include the entity in collision checking.
    ; The Collision Type instance gets updated by updateCollisions
    ; if any collisions with this entity occur
    ; --------------------------------------------------------
    a\collisionInfo = addCollisionEntity(a\entity,radius)

    a\xspeed# = xspeed#
    a\yspeed# = yspeed#
    a\hp = 512
    NameEntity a\entity,Handle(a) ; setup Type instance <-> entity association
End Function

; ------------------------------------------------------------------------------------------------------------------------------------

Function updateThings()

    ; iterate through things
    thingCount = 0
    For a.Thing = Each Thing
        ; -------------------------------------------------------------
        ; Check the Collision instance to see if a collision has been
        ; flagged or not and handle the collision accordingly
        ; Collision normals are accessible via the cNx & cNz fields.
        ; -------------------------------------------------------------
        If a\collisionInfo\hasCollided
            EntityColor a\entity,0,512,512
            hitThing(a\entity)
        Else
            EntityColor a\entity,255,a\hp,0
        End If

        If a <> Null ; only update if entity hasn't already been deleted

            ; keep thing within boundary
            If EntityX(a\entity,True) < -16 Or EntityX(a\entity,True) > 16
                a\xspeed = - a\xspeed
            End If

            If EntityZ(a\entity,True) < -12 Or EntityZ(a\entity,True) > 12
                a\yspeed = - a\yspeed
            End If

            If Abs(a\xspeed) > .1 a\xspeed = a\xspeed * .99 ; max speed dampner
            If Abs(a\yspeed) > .1 a\yspeed = a\yspeed * .99

            ; move the thing
            TranslateEntity a\entity,a\xspeed,0,a\yspeed
            thingCount = thingCount + 1

        End If

    Next

End Function
; -------------------
; handle a collision
; -------------------

Function hitThing(entity)

    ; get the Type instance associated with the entity
    a.Thing = Object.Thing(EntityName(entity))

    currentSpeed# = Sqr((a\xspeed * a\xspeed) + (a\yspeed * a\yspeed))

    ; decide how to handle the collision
    Select collisionResponseMode
        Case 1
            a\xspeed = a\xspeed + ((a\collisionInfo\cNx * currentSpeed#) ) * .1
            a\yspeed = a\yspeed + ((a\collisionInfo\cNz * currentSpeed#) ) * .1
        Case 2
            a\xspeed = a\collisionInfo\cNx * currentSpeed#
            a\yspeed = a\collisionInfo\cNz * currentSpeed#
    End Select

    a\hp = a\hp - 1
    If a\hp <= 0
        ; remove entity making sure to delete the related collision instance !
        Delete a\collisionInfo
        FreeEntity a\entity
        Delete a
    End If

End Function



; ====================================================================================================================================



Note that I'm using the x,z axis instead of x,y. Just a legacy thing because of the way the camera pointed when I started out ;)

You can grab upx here: http://upx.sourceforge.net/
http://upx.sourceforge.net/download/unstable/upx193w.zip

run like: "upx -9 myfinalgame.exe"