Jump to content

Recommended Posts

Posted

When I fly around and shoot then the movement of the ship is jerky - without shooting the movement is ok!

CPU usage is low during game play!

Nice work :D

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted (edited)

When I fly around and shoot then the movement of the ship is jerky - without shooting the movement is ok!

CPU usage is low during game play!

Nice work :D

UEZ

Doesn't seem jerky here - only slightly slower.

I can explain the slowing-down when a "shot" is added, an empty spot in the Shots array has to be searched for - likewise, non-empty ones are searched for during drawing; and of course - having to calculate and draw more shots certainly will slow it also. (Not mentioning the rapid playing of sounds)

However, I may be missing a detail here - but eh.

Perhaps I should use a timer-substitute for the Sleep(50) call so that it tries to use the same amount of time on each loop

[instead of the same amount of time on that specific delay - that is, make the delay .... adjustable]

this will be at the sacrifice of some CPU when the battle gets hairy, though.

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

Posted (edited)

at that level it will also be hard to time accurately enough.

I recommend to + 1 to a variable on shoot, and sleep (50 - $var). Play around, you might want more than 1...

MDiesel

Just did some testing and Timers seem to work okay.

You can set an FPS via the Desired FPS box - the game will try to get as close to that FPS as possible.

(Note: I know the FPS box takes the keyboard input while playing - click the game's graphics area to disable/enab;e the input)

Personally, I'm running at ~10 FPS. (ugh, but I have a crappy machine and this IS just GDI+ on AutoIt)

EDIT: fixed the keyboard input issue by focusing an off-screen button that's unused.

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

  • 11 months later...
Posted (edited)

Global $Sounds[4] = ['shot', 'expl', 'boom', 'phaser']
For $i = 0 To 3
    $Sounds[$i] = _SoundOpen(@ScriptDir & '\' & $Sounds[$i] & '.wav')
Next

_SoundOpen() returns a 3 element array which you're then tyring to load into one element of an array. That's what it seems to me at least. Also, SoundOpen only accepts one parameter.

Edit: Anyone care to try this and tell me if this works, please? (Download the sound files from the OP if you haven't yet done so.

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Res_Fileversion=0.0.0.0
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=y
#AutoIt3Wrapper_AU3Check_Parameters=-w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -d -I "D:\AutoIt\AutoIt Scripts\Includes"
#AutoIt3Wrapper_Run_After=md "%scriptdir%\Versions\%fileversion%"
#AutoIt3Wrapper_Run_After=copy "%in%" "%scriptdir%\Versions\%fileversion%\%scriptfile%%fileversion%.au3"
#AutoIt3Wrapper_Run_After=copy "%out%" "%scriptdir%\Versions\%fileversion%\%scriptfile%%fileversion%.exe"
#AutoIt3Wrapper_Run_Tidy=y
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Misc.au3>
#include <Sound.au3>
#include <Array.au3>

Opt("GUIOnEventMode", 1)
#region ### START Koda GUI section ### Form=
Global $Form1 = GUICreate("StarShooter v2", 339, 428, 193, 115)
GUISetOnEvent($GUI_EVENT_CLOSE, 'GUI_Exit')

Global $Label1 = GUICtrlCreateLabel("[Graphics Object]", 1, 0, 335, 394, -1, $WS_EX_STATICEDGE)
GUICtrlSetColor(-1, 0x00FF00)
GUICtrlSetBkColor(-1, 0x000000)

Global $StatLab = GUICtrlCreateLabel("", 1, 394, 300, 20)
GUICtrlSetColor(-1, 0x00FF00)
GUICtrlSetBkColor(-1, 0x000000)
#endregion ### END Koda GUI section ###

;GDI Setup
Global $cHWnd = GUICtrlGetHandle($Label1)
Global $cPos = ControlGetPos($Form1, '', $Label1)
_GDIPlus_Startup()
Global $gro = _GDIPlus_GraphicsCreateFromHWND($cHWnd)
Global $grb = _GDIPlus_BitmapCreateFromGraphics($cPos[2], $cPos[3], $gro)
Global $gr = _GDIPlus_ImageGetGraphicsContext($grb)

;Game Vars
Global $Green_Pen = _GDIPlus_PenCreate(0xFF00FF00)
Global $Red_Pen = _GDIPlus_PenCreate(0xFFFF0000)
Global $Yellow_Pen = _GDIPlus_PenCreate(0xFFFF7F00)
Global $Green_Brush = _GDIPlus_BrushCreateSolid(0xFF00FF00)
Global $Red_Brush = _GDIPlus_BrushCreateSolid(0xFFFF0000)
Global $tmpPen = 0
Global $Pi = 3.14159
Global $DegToRad = $Pi / 180
Global $RadToDeg = 180 / $Pi
Global $ShipTypeHP[3] = [10, 20, 40]
Global $Keys[5] = ['25', '27', '28', '26', '20']
Global $Player[11] = [100, 100, 20, 90, 0, 0, 0, 0, 0, 0, 0]
Global $PlayerSpeed = 10
Global $PlayerTurnR = 10
Global $PlayerInput = True
Global $CanFire = True
Global $EnemiesCanFire = True

;$Player[10]=2
Global $PlayerHPRatio = 110 / $ShipTypeHP[$Player[10]]
Global $PlayerHP = $ShipTypeHP[$Player[10]] * $PlayerHPRatio;9999999 if you want to cheat....
Global $PlayerDmgToHPRatio = 0.8
Global $PlayerShpToHPRatio = 2

Global $WingFired = 0

Global $ShotW = 5
Global $ShotX = 99
Global $ShotRange = 10; movements, not px
Global $Shots[$ShotX + 1][8];0 shot?, 1 x, 2 y, 3 a, 4 pen, 5 moves, 6 owner, 7 type
Global $ShotError = 10; degrees
Global $ShotSpeed = $ShotW * 3

Global $FighterDamage = 6

Global $AnimationN = 0
Global $AnimationI = 0

Global $EnemiesX = 49
Global $Enemies[$EnemiesX + 1][16]
Global $TargetLines = False

Global $HitsX = 99
Global $Hits[$HitsX + 1][4]

Global $Anim3_Timer = TimerInit()
Global $AIShotDelay = 250

Global $Wins = 0
Global $Level = 0
Global $Playing = True


Global $Phaser = _SoundOpen(@ScriptDir & '\phaser.wav')
Global $Shot = _SoundOpen(@ScriptDir & '\shot.wav')
Global $Explode = _SoundOpen(@ScriptDir & '\expl.wav')
Global $Boom = _SoundOpen(@ScriptDir & '\boom.wav')

ClearField()

;Game Init
GUISetState(@SW_SHOW)

While $Playing
    If $PlayerHP < 0 Then
        Play($Boom)
        UpdateScore()
        MsgBox(0, '', 'You have died!')
        $PlayerHP = $ShipTypeHP[$Player[10]] * $PlayerHPRatio
        $Level = 0
        ClearField()
        $Anim3_Timer = TimerInit()
    EndIf

    If $PlayerHP > 50 And TimerDiff($Anim3_Timer) > 60000 Then
        If $AnimationN = 0 Then
            $AnimationN = 3
            $Anim3_Timer = TimerInit()
        EndIf
    EndIf

    If Not EnemyExists() And $AnimationN = 0 Then
        $Level += 1

        Select
            Case $Level <= 3
                For $n = 1 To $Level
                    AddEnemy(Random(50, $cPos[2] - 50, 1), Random(50, $cPos[3] - 50, 1), -1, $Red_Pen, 0)
                Next
            Case $Level <= 6
                For $n = 1 To $Level - 3
                    If $n = 1 Then
                        AddEnemy(Random(50, $cPos[2] - 50, 1), Random(50, $cPos[3] - 50, 1), -1, $Red_Pen, 1)
                    Else
                        AddEnemy(Random(50, $cPos[2] - 50, 1), Random(50, $cPos[3] - 50, 1), -1, $Red_Pen, 0)
                    EndIf
                Next
            Case $Level <= 9
                For $n = 1 To $Level - 6
                    If $n = 1 Or $n = 3 Then
                        AddEnemy(Random(50, $cPos[2] - 50, 1), Random(50, $cPos[3] - 50, 1), -1, $Red_Pen, 1)
                    Else
                        AddEnemy(Random(50, $cPos[2] - 50, 1), Random(50, $cPos[3] - 50, 1), -1, $Red_Pen, 0)
                    EndIf
                Next
            Case $Level <= 12
                For $n = 1 To $Level - 9
                    AddEnemy(Random(50, $cPos[2] - 50, 1), Random(50, $cPos[3] - 50, 1), -1, $Red_Pen, 1)
                Next
            Case $Level = 13
                If Not $AnimationN = 0 Then
                    $AnimationI = 0
                    $AnimationN = 2
                EndIf
            Case $Level = 15
                For $i = 1 To $Wins + 1
                    AddEnemy(Random(50, $cPos[2] - 50, 1), Random(50, $cPos[3] - 50, 1), -1, $Red_Pen, 2, 40)
                Next
            Case $Level = 17
                MsgBox(0, '', 'You won!' & @CRLF & 'Continue playing for advanced challenges.')
                ;$PlayerHP=200; hehehe ;) - winners benefits.
                $PlayerSpeed *= 1.5
                $PlayerTurnR *= 1.5
                $FighterDamage *= 1.5
                $AIShotDelay /= 1.5
                $Level = 0
                $Wins += 1
                If $Player[10] < 2 Then $Player[10] += 1; yes you get a ship upgrade (visually)
                If $Player[10] = 2 Then $Player[2] = 40
                $PlayerHP = $ShipTypeHP[$Player[10]] * $PlayerHPRatio
                ClearField()
        EndSelect

        ;If $Level=4 Then $AnimationN=1
    EndIf

    _GDIPlus_GraphicsClear($gr, 0xFF000000)
    AnimCheck(); things the user cannot control.
    MoveCheck()
    DrawPlane()
    Sleep(50)
WEnd

$tmpPen = 0
_GDIPlus_PenDispose($Yellow_Pen)
_GDIPlus_PenDispose($Red_Pen)
_GDIPlus_PenDispose($Green_Pen)
_GDIPlus_BrushDispose($Red_Brush)
_GDIPlus_BrushDispose($Green_Brush)
_GDIPlus_GraphicsDispose($gr)
_GDIPlus_BitmapDispose($grb)
_GDIPlus_GraphicsDispose($gro)
_GDIPlus_Shutdown()

;~ For $i = 0 To 3
;~  _SoundClose($Sounds[$i])
;~ Next

Exit

Func Play($sound)
    Local Static $Tsound = TimerInit()

;~  If ($sound = $Shot Or $sound = $Phaser) And TimerDiff($Tsound) < 250 Then Return; because Shots are fired VERY often

    Switch _SoundStatus($sound)
        Case 'not ready'
            Return
        Case 'playing'
            If $sound[0] == $Phaser[0] Then Return

            If $sound[0] == $Shot[0] Then
                If TimerDiff($Tsound) < 50 Then Return
            EndIf
    EndSwitch

    _SoundPlay($sound)
    ;ConsoleWrite(@error&' '&$Sounds&@CRLF)
EndFunc ;==>Play

Func DrawPlane()
    $tmpPen = $Green_Pen

    If $PlayerHP > 100 Then
        _GDIPlus_GraphicsDrawEllipse($gr, $Player[0] - ($Player[2] * 0.5 + 5), $Player[1] - ($Player[2] * 0.5 + 5), $Player[2] + 10, $Player[2] + 10, $tmpPen)
    EndIf

    Ship($Player[10], $Player[0], $Player[1], $Player[2], $Player[3], $Player[4], $Player[5], $Player[6], $Player[7], $Player[8], $Player[9])

    For $i = 0 To $ShotX
        If $Shots[$i][0] = 1 Then
            If ($Shots[$i][7] = 0 And $Shots[$i][5] > $ShotRange) Then ;Or $Shots[$i][1]<-5 Or $Shots[$i][1]>$cPos[2]+5 Or $Shots[$i][2]<-5 Or $Shots[$i][2]>$cPos[3]+5 Then
                ;ConsoleWrite('Del Shot'&@CRLF)
                $Shots[$i][0] = 0
;~              ContinueLoop
            EndIf
            _CircValue($Shots[$i][1], 0, $cPos[2])
            _CircValue($Shots[$i][2], 0, $cPos[3])

            $tmpPen = $Shots[$i][4]
            ShotCollision($i, $Shots[$i][1], $Shots[$i][2])
            ;Shot(Byref $type,Byref $x,Byref $y,Byref $a)
            If $Shots[$i][0] = 1 Then Shot($Shots[$i][7], $Shots[$i][1], $Shots[$i][2], $Shots[$i][3])
            MoveAngle($Shots[$i][1], $Shots[$i][2], $Shots[$i][3], $ShotSpeed)
            $Shots[$i][5] += 1
        EndIf
    Next

    For $i = 0 To $HitsX
        If $Hits[$i][0] > 0 Then
            _GDIPlus_GraphicsFillEllipse($gr, $Hits[$i][1], $Hits[$i][2], $Hits[$i][0], $Hits[$i][0], $Hits[$i][3])
            $Hits[$i][0] -= 2
        EndIf
    Next

    For $i = 0 To $EnemiesX
        If $Enemies[$i][0] = 1 Then
            #cs
                If $Enemies[$i][1]<-50 Or $Enemies[$i][1]>$cPos[2]+50 Or $Enemies[$i][2]<-50 Or $Enemies[$i][2]>$cPos[3]+50 Then
                ;ConsoleWrite('Del Shot'&@CRLF)
                $Enemies[$i][0]=0
                ContinueLoop
                EndIf
            #ce
            _CircValue($Enemies[$i][1], 0, $cPos[2])
            _CircValue($Enemies[$i][2], 0, $cPos[3])

            $tmpPen = $Enemies[$i][5]
            Ship($Enemies[$i][12], $Enemies[$i][1], $Enemies[$i][2], $Enemies[$i][3], $Enemies[$i][4], $Enemies[$i][6], $Enemies[$i][7], $Enemies[$i][8], $Enemies[$i][9], $Enemies[$i][10], $Enemies[$i][11])
            EMove($i)
        EndIf
    Next

    UpdateScore()

    _GDIPlus_GraphicsDrawImageRect($gro, $grb, 0, 0, $cPos[2], $cPos[3]) ;copy to bitmap
EndFunc ;==>DrawPlane

Func UpdateScore($Forced = False)
    Global $UpTimer

    If $Forced Or TimerDiff($UpTimer) > 500 Then
        GUICtrlSetData($StatLab, 'Health: ' & Int($PlayerHP) & '/100 - Level: ' & $Level)
        $UpTimer = TimerInit()
    EndIf
EndFunc ;==>UpdateScore

Func EnemyExists()
    For $i = 0 To $EnemiesX
        If $Enemies[$i][0] = 1 Then Return True
    Next
    Return False
EndFunc ;==>EnemyExists

Func ClearField()
    For $i = 0 To $EnemiesX
        $Enemies[$i][0] = 0
    Next

    For $i = 0 To $ShotX
        $Shots[$i][0] = 0
    Next

    For $i = 0 To $HitsX
        ;ConsoleWrite($i&'/'&$HitsX&@CRLF)
        $Hits[$i][0] = 0
    Next

    $AnimationN = 0
    $AnimationI = 0
EndFunc ;==>ClearField

Func AnimCheck()
    Switch $AnimationN
        Case 1
            $CanFire = False
            $PlayerInput = False

            If $AnimationI < 60 Then
                $Player[3] += $AnimationI
            Else
                $Player[3] += (100 - $AnimationI)

                If (100 - $AnimationI) <= 0 Then
                    $AnimationN = 0
                    $PlayerInput = True
                    $CanFire = True
                    $AnimationI = 0
                    Return
                EndIf
            EndIf

            Switch $AnimationI
                Case 53
                    $CanFire = True
                    For $i = 1 To 360 Step 5
                        AddShot($Player[0], $Player[1], $i, $Green_Pen, 1, 1)
                    Next
                    $CanFire = False
            EndSwitch

            $AnimationI += 1
        Case 2; placeholder animation for final battle (nonexistant level 14)
            $Level = 14
            $AnimationN = 0
            $AnimationI = 0
        Case 3
            Global $Anim3_X, $Anim3_Y, $Anim3_S, $Anim3_A

            If $AnimationI = 1 Then
                $Anim3_Y = Random(50, $cPos[3] - 50, 1)
                Switch (Random(1, 100) < 50)
                    Case True
                        $Anim3_A = 0
                        $Anim3_X = 0
                        $Anim3_S = 5
                    Case False
                        $Anim3_A = 180
                        $Anim3_X = $cPos[2]
                        $Anim3_S = -5
                EndSwitch
            EndIf

            If $AnimationI > 1 And $AnimationI < 161 Then
                Local $type = 2, $y = $Anim3_Y, $w = 40, $wx = 60, $w2 = 30, $a = 180
                Local $Head_x, $Head_y, $WingL_x, $WingL_y, $WingR_x, $WingR_y

                $Anim3_X += $Anim3_S
;~              Local $ttmpPen = $tmpPen
                $tmpPen = $Red_Pen
                _GDIPlus_GraphicsDrawEllipse($gr, $Anim3_X - $w2, $y - $w2, $wx, $wx, $Yellow_Pen)
                Ship($type, $Anim3_X, $y, $w, $Anim3_A, $Head_x, $Head_y, $WingL_x, $WingL_y, $WingR_x, $WingR_y)

                Global $Anim3_T

                If $Anim3_X > 5 And $Anim3_X < $cPos[2] - 5 And TimerDiff($Anim3_T) > 3000 Then
                    Local $pX = $Player[0]
                    Local $pY = $Player[1]
                    Local $dX = $pX - $Anim3_X
                    Local $dY = $pY - $y
;~                  Local $Hyp = ($dX ^ 2) + ($dY ^ 2)
                    $a = ATan($dX / $dY) * $RadToDeg + 90
                    If $dY >= 0 Then $a += 180
                    _CircValue($a, 0, 360)
                    AddShot($Anim3_X, $y, $a, $Red_Pen, 1, 2, 1)
                    $Anim3_T = TimerInit()
                EndIf
            EndIf

            If $AnimationI > 1 And ($AnimationI = 160 Or $Anim3_X < -50 Or $Anim3_X > $cPos[2] + 50) Then
                $AnimationN = 0
                $AnimationI = 0
                Return
            EndIf

            $AnimationI += 1
    EndSwitch
EndFunc ;==>AnimCheck

Func MoveCheck()
    If Not $PlayerInput Then Return
    ;Ship Angle changes
    If _IsPressed(Hex(Asc('A'), 2)) Then $AnimationN = 2
    If _IsPressed(Hex(Asc('S'), 2)) Then $AnimationN = 3
    If _IsPressed(Hex(Asc('D'), 2)) Then $AnimationN = 1
    If _IsPressed($Keys[0]) Then $Player[3] += $PlayerTurnR
    If _IsPressed($Keys[1]) Then $Player[3] -= $PlayerTurnR

    ;Ship Movement
    Local $AMoveS = 0

    If _IsPressed($Keys[2]) Then $AMoveS = -1; reverse - on a spaceship!? I think not.

    If _IsPressed($Keys[3]) Then $AMoveS = 1

    If $AMoveS <> 0 Then
        MoveAngle($Player[0], $Player[1], $Player[3], $PlayerSpeed * $AMoveS)
        _CircValue($Player[0], 0, $cPos[2])
        _CircValue($Player[1], 0, $cPos[3])
        ;iLimit($Player[0],0,$cPos[2])
        ;iLimit($Player[1],0,$cPos[3])
    EndIf

    If _IsPressed($Keys[4]) Then
        Local $sX, $sY

        Switch $WingFired
            Case 0
                $WingFired = 1
                $sX = $Player[8]
                $sY = $Player[9]
                AddShot($sX, $sY, $Player[3] + 5, $Green_Pen, 1, 1); ,1)
            Case 1
                $WingFired = 0
                $sX = $Player[6]
                $sY = $Player[7]
                AddShot($sX, $sY, $Player[3] - 5, $Green_Pen, 1, 1); ,1)
        EndSwitch
    EndIf
EndFunc ;==>MoveCheck

Func iLimit(ByRef $i, $n, $x)
    If $i < $n Then $i = $n
    If $i > $x Then $i = $x
EndFunc ;==>iLimit

Func EMove($iE)
    If $Enemies[$iE][0] = 0 Then Return

    Local $pX = $Player[0]
    Local $pY = $Player[1]

    ;limit only if we want the units to turn away from the edge
    ;iLimit($pX,50,$cPos[2]-50)
    ;iLimit($pY,50,$cPos[3]-50)

    Local $dX = $pX - $Enemies[$iE][1]
    Local $dY = $pY - $Enemies[$iE][2]
;~  Local $Hyp = ($dX ^ 2) + ($dY ^ 2)
    Local $a = ATan($dX / $dY) * $RadToDeg + 90
    Local $bHeavy = ($Enemies[$iE][12] == 1)
    Local $bDread = ($Enemies[$iE][12] == 2)

    Local $espd, $turn

    If $bHeavy Or $bDread Then
        $tmpPen = $Yellow_Pen; shots are yellow/orange for higher damage
        If $bHeavy Then
            $espd = $PlayerSpeed
            $turn = $PlayerTurnR
        Else; bDread
            $espd = $PlayerSpeed / 1.5;*3.5
            $turn = $PlayerTurnR
        EndIf
    Else
        $espd = $PlayerSpeed * 0.8
        $turn = $PlayerTurnR * 2
    EndIf

    If $dY >= 0 Then $a += 180

    If $TargetLines Then Line($Enemies[$iE][1], $Enemies[$iE][2], 100, $a); Targetting Line

    Local $dist = Sqrt(($dX ^ 2) + ($dY ^ 2))

    _CircValue($Enemies[$iE][4], 0, 359)
    _CircValue($a, 0, 359)

    Local $sa1, $sa2

    SweepDistance_Short($sa1, $a, $Enemies[$iE][4] - $turn); originally -1, +1
    SweepDistance_Short($sa2, $a, $Enemies[$iE][4] + $turn)

    Local $saN, $saSign = 1

    Select
        Case $sa1 <= $sa2
            $saN = $sa1
            $saSign = -1
        Case $sa2 < $sa1
            $saN = $sa2
    EndSelect

    $sa1 = 0
    $sa2 = 0

    ;ConsoleWrite('Current Angle: '&$Enemies[$iE][4]&@CRLF)
    ;ConsoleWrite('Desired Angle: '&$a&@CRLF)
    ;ConsoleWrite('Shortest Dist: '&SweepDistance_Short($a,$Enemies[$iE][4])&@CRLF)
    ;ConsoleWrite($sa1&' '&$sa2&@CRLF)

    Local $phRangeP = ($Player[10] + 1) * 30
    Local $phRangeE = ($Enemies[$iE][12] + 1) * 30
    Local $bFirePhasersE = True
    Local $inRange = ($dist <= ($ShotRange * $ShotW) * 3.5)

    If $saN < 45 Then
        $bFirePhasersE = False
    EndIf

    Local $FireShots = False

    If $CanFire Then
        $FireShots = True
        Local $dmg
        Local $hsz
        If $dist <= $phRangeP Then
            ;;If True Then;TimerDiff($PPhaserTimer)>($AIShotDelay/2) Then
            $hsz = 10
;~          Local $w2 = 10;20/2
;~          Local $xn = $Enemies[$iE][1] - $w2
;~          Local $xe = $Enemies[$iE][1] + $w2
;~          Local $yn = $Enemies[$iE][2] - $w2
;~          Local $ye = $Enemies[$iE][2] + $w2

            Local $x = $Enemies[$iE][1]
            Local $y = $Enemies[$iE][2]

            Play($Phaser)
            _GDIPlus_GraphicsDrawLine($gr, $x, $y, $Player[0], $Player[1], $Green_Pen)
            $dmg = $Enemies[$iE][15] / (20 * (3 - $Player[10]))
            If $dmg < 0.5 Then $dmg = 0.5
            $Enemies[$iE][15] -= $dmg
            If $Enemies[$iE][15] < 0 Then
                For $an = 1 To 360 Step 45
                    AddShot($Enemies[$iE][1], $Enemies[$iE][2], $an, $Red_Pen, 1, 2)
                Next
                $Enemies[$iE][0] = 0
                $Enemies[$iE][1] = 0
                $Enemies[$iE][2] = 0
                $hsz *= 2
                Play($Boom)
            EndIf
            $PlayerHP += $dmg * ($PlayerDmgToHPRatio + ($Enemies[$iE][12] / $PlayerShpToHPRatio))
            AddHit($hsz, $x, $y, $Green_Brush)

;~          Global $PPhaserTimer = TimerInit()

            ;EndIf
        EndIf
        If $Enemies[$iE][0] = 0 Then Return
        If $EnemiesCanFire And $bFirePhasersE And $dist <= $phRangeE Then
            ;If TimerDiff($Enemies[$iE][13])>($AIShotDelay/2) Then
            $hsz = 10
;~          $w2 = $Player[2] / 2
;~          Local $xn = $Player[0] - $w2
;~          Local $xe = $Player[0] + $w2
;~          Local $yn = $Player[1] - $w2
;~          Local $ye = $Player[1] + $w2

            $x = $Player[0]
            $y = $Player[1]

            Play($Phaser)
            $dmg = $PlayerHP / (20 * (3 - $Enemies[$iE][12]))
            If $dmg < 0.5 Then $dmg = 0.5
            _GDIPlus_GraphicsDrawLine($gr, $Enemies[$iE][1], $Enemies[$iE][2], $x, $y, $tmpPen)
            $PlayerHP -= $dmg
            $FireShots = False
            $Enemies[$iE][13] = TimerInit()
            If $PlayerHP < 0 Then $hsz *= 2

            AddHit($hsz, $x, $y, $Red_Brush)
            $FireShots = False
            ;EndIf
            ;EndIf
        EndIf
    EndIf

    Local $bTurn = False
    Local $bMove = True

    Switch $Enemies[$iE][12]
        Case 2
            If $dist > 90 Then
                If $saN > 10 Then
                    $bTurn = True
                    $bMove = False
                    $FireShots = True
                EndIf

                If $saN <= 90 Then
                    $FireShots = True
                    $bMove = True
                EndIf
            Else
                $bTurn = False
                $bMove = True
                $FireShots = True
            EndIf
        Case 1
            If ($saN > 35 And $dist > 30) Then
                $bTurn = True
                $FireShots = False
                $espd *= 0.5
                ;Else
                ;   If $inRange Then $bMove=False
            EndIf
        Case 0
            If ($saN > 35 And $dist > 30) Then
                $bTurn = True
                $FireShots = False
            EndIf
    EndSwitch

    ;add this only to force enemies to move forward only back onto the field when at the edge
    #cs
        If $Enemies[$iE][1]<0 Or $Enemies[$iE][1]>$cPos[2] Or $Enemies[$iE][2]<0 Or $Enemies[$iE][2]>$cPos[3] Then
        If $saN>10 Then
        $bTurn=True
        $bMove=False
        EndIf
        EndIf
    #ce

    If $bTurn Then
        iLimit($saN, 0, $turn)
        $Enemies[$iE][4] += $saSign * $saN
    EndIf

    If $CanFire And $FireShots And $EnemiesCanFire Then
        Local $tmpShipFire = False
        Local $firetype = 0
        If TimerDiff($Enemies[$iE][13]) > $AIShotDelay Then

            If $bDread Then

                If Random(1, 100, 1) <= 10 Then
                    $firetype = 1
                    $tmpShipFire = True
                Else

                    If (Not $inRange) Then $Enemies[$iE][13] = TimerInit()
                EndIf
            EndIf

            If (Not $tmpShipFire) And $inRange Then $tmpShipFire = True

            If $tmpShipFire Then
                Switch $Enemies[$iE][14]; your enemies' cannons are much less efficient and sometimes jam. ;)
                    Case 0
                        AddShot($Enemies[$iE][8], $Enemies[$iE][9], $a, $tmpPen, 1, 0, $firetype);$Enemies[$iE][4]
                        $Enemies[$iE][14] = 1
                    Case 1
                        AddShot($Enemies[$iE][10], $Enemies[$iE][11], $a, $tmpPen, 1, 0, $firetype)
                        $Enemies[$iE][14] = 0
                EndSwitch
                $Enemies[$iE][13] = TimerInit()
            EndIf
        EndIf
    EndIf

    If $bMove Then MoveAngle($Enemies[$iE][1], $Enemies[$iE][2], $Enemies[$iE][4], $espd)

EndFunc ;==>EMove

Func SweepDistance_Short(ByRef $angle, $a1, $a2)
    $angle = Mod((Abs($a1 - $a2)), 360)

    If $angle > 180 Then $angle = 360 - $angle
EndFunc ;==>SweepDistance_Short

Func AddEnemy($x, $y, $a, $pen, $type = 0, $w = 20, $hp = -1)
    If $a = -1 Then $a = Random(1, 360, 0)

    For $i = 0 To $EnemiesX

        If $Enemies[$i][0] = 0 Then
            $Enemies[$i][0] = 1
            $Enemies[$i][1] = $x
            $Enemies[$i][2] = $y
            $Enemies[$i][3] = $w;w
            $Enemies[$i][4] = $a
            $Enemies[$i][5] = $pen

            For $iii = 6 To 11
                $Enemies[$i][$iii] = 0
            Next

            $Enemies[$i][12] = $type
            $Enemies[$i][13] = 0
            $Enemies[$i][14] = 0

            If $hp = -1 Then
                $Enemies[$i][15] = $ShipTypeHP[$type]
            Else
                $Enemies[$i][15] = $hp
            EndIf

            Return $i
        EndIf
    Next

    Return -1
EndFunc ;==>AddEnemy

Func AddHit($hsz, $x, $y, $brush)
    _CircValue($x, 0, $cPos[2])
    _CircValue($y, 0, $cPos[3])

    For $ii = 0 To $HitsX

        If $Hits[$ii][0] <= 0 Then
            $Hits[$ii][0] = $hsz
            $Hits[$ii][1] = $x
            $Hits[$ii][2] = $y
            $Hits[$ii][3] = $brush
            Play($Explode)
            ExitLoop
        EndIf
    Next
EndFunc ;==>AddHit

Func AddShot($x, $y, $a, $pen, $n = 1, $owner = 0, $type = 0)
    If Not $CanFire Then Return

    For $ii = 1 To $n

        For $i = 0 To $ShotX

            If $Shots[$i][0] = 0 Then
                ;ConsoleWrite('Add Shot'&@CRLF)
                $Shots[$i][0] = 1
                $Shots[$i][1] = $x
                $Shots[$i][2] = $y
                $Shots[$i][3] = $a + Random(-1 * $ShotError, $ShotError, 1)
                $Shots[$i][4] = $pen
                $Shots[$i][5] = 0
                $Shots[$i][6] = $owner
                $Shots[$i][7] = $type
                ExitLoop
            EndIf
        Next
    Next
    Play($Shot)
EndFunc ;==>AddShot

Func Shot(ByRef $type, ByRef $x, ByRef $y, ByRef $a)
    Switch $type
        Case 0
            Line($x, $y, $ShotW, $a)
        Case 1
            For $i = 1 To 360 Step 45
                Line($x, $y, $ShotW, $i)
            Next
    EndSwitch
EndFunc ;==>Shot

Func Ship(ByRef $type, ByRef $x, ByRef $y, ByRef $w, ByRef $a, ByRef $Head_x, ByRef $Head_y, ByRef $WingL_x, ByRef $WingL_y, ByRef $WingR_x, ByRef $WingR_y)
    Global $Line_x, $Line_y
    Local $w2 = $w * 0.5
    Local $w4 = $w2 * 0.5
    Local $w8 = $w4 * 0.5

    Switch $type
        Case 0
            Line($x, $y, $w2, $a) ;     |---> head
            $Head_x = $Line_x
            $Head_y = $Line_y
            Line($x, $y, $w2, $a + 180) ; <---|     tail

            Line($x, $y, $w2, $a + 90);     +^  wing L
            $WingL_x = $Line_x
            $WingL_y = $Line_y
            Line($x, $y, $w2, $a - 90);     +,  wing R
            $WingR_x = $Line_x
            $WingR_y = $Line_y

            Line($Head_x, $Head_y, $w2, $a + 153) ;--\ nose
            Line($Head_x, $Head_y, $w2, $a - 153) ;--/

            Line($WingL_x, $WingL_y, $w4, $a)
            $WingL_x = $Line_x
            $WingL_y = $Line_y
            Line($WingR_x, $WingR_y, $w4, $a)
            $WingR_x = $Line_x
            $WingR_y = $Line_y
        Case 1
            Line($x, $y, $w2, $a) ;     |---> head
            $Head_x = $Line_x
            $Head_y = $Line_y
            Line($x, $y, $w2, $a + 135)
            $WingL_x = $Line_x
            $WingL_y = $Line_y
            Line($x, $y, $w2, $a - 135)
            $WingR_x = $Line_x
            $WingR_y = $Line_y
            _GDIPlus_GraphicsDrawEllipse($gr, $x - $w2, $y - $w2, $w, $w, $tmpPen)
            Line($WingL_x, $WingL_y, $w, $a)
            $WingL_x = $Line_x
            $WingL_y = $Line_y
            Line($WingR_x, $WingR_y, $w, $a)
            $WingR_x = $Line_x
            $WingR_y = $Line_y
        Case 2
            Line($x, $y, $w2, $a) ;     |---> head
            $Head_x = $Line_x
            $Head_y = $Line_y
            Line($x, $y, $w2, $a + 180) ; <---|     tail
            Local $Tail_x = $Line_x, $Tail_y = $Line_y

            Line($Head_x, $Head_y, $w2 + $w8, $a + 153) ;--\ nose
            Line($Head_x, $Head_y, $w2 + $w8, $a - 153) ;--/

            Line($x, $y, $w2 - $w8, $a + 45);   +^  wing L
            $WingL_x = $Line_x
            $WingL_y = $Line_y
            Line($x, $y, $w2 - $w8, $a - 45);   +,  wing R
            $WingR_x = $Line_x
            $WingR_y = $Line_y

            Line($WingR_x, $WingR_y, $w2, $a - 180)
            Line($WingR_x, $WingR_y, $w8, $a - 90)
            Line($Line_x, $Line_y, $w2, $a - 180)
            Local $lax = $Line_x, $lay = $Line_y
            Line($Line_x, $Line_y, $w4, $a - 180)

            Line($WingL_x, $WingL_y, $w2, $a - 180)
            Line($WingL_x, $WingL_y, $w8, $a + 90)
            Line($Line_x, $Line_y, $w2, $a - 180)
            _GDIPlus_GraphicsDrawLine($gr, $Line_x, $Line_y, $Tail_x, $Tail_y, $tmpPen)
            _GDIPlus_GraphicsDrawLine($gr, $lax, $lay, $Tail_x, $Tail_y, $tmpPen)
            Line($Line_x, $Line_y, $w4, $a - 180)

            Line($WingL_x, $WingL_y, $w4, $a)
            $WingL_x = $Line_x
            $WingL_y = $Line_y
            Line($WingR_x, $WingR_y, $w4, $a)
            $WingR_x = $Line_x
            $WingR_y = $Line_y
    EndSwitch
EndFunc ;==>Ship

Func ShotCollision(ByRef $iS, ByRef $x, ByRef $y)
    If $Shots[$iS][0] = 0 Then Return
    Local $pen = $Shots[$iS][4]
    Local $bDetonate = False

    ; don't modify this for cross-screen support, torpedos need to be limited by the window to detonate sooner
    If $x < 10 Or $x > $cPos[2] - 10 Or $y < 10 Or $y > $cPos[3] - 10 Then $bDetonate = True

    For $i = -1 To $EnemiesX
        Local $w2
        Local $xn, $xe, $yn, $ye

        If $i = -1 Then

            If $Shots[$iS][6] = 1 Then ContinueLoop
            $w2 = $Player[2] / 2
            $xn = $Player[0] - $w2
            $xe = $Player[0] + $w2
            $yn = $Player[1] - $w2
            $ye = $Player[1] + $w2

            If ($x >= $xn And $x <= $xe) And ($y >= $yn And $y <= $ye) Then
                $bDetonate = True
                $Shots[$iS][0] = 0
                ;ConsoleWrite('Player Hit'&@CRLF)

                Local $hsz = 10

                Local $dmg = $FighterDamage

                If $pen = $Yellow_Pen Then
                    $hsz *= 1.5
                    $dmg *= 2
                EndIf

                If $PlayerHP > 100 Then
                    $hsz *= 0.5
                    $PlayerHP -= $dmg * 0.25; shielded
                Else
                    $PlayerHP -= $dmg
                EndIf

                AddHit($hsz, $x, $y, $Red_Brush)

                ExitLoop
            EndIf
        Else
            If $Shots[$iS][6] = 0 Then ExitLoop

            If $Enemies[$i][0] = 1 Then
                $hsz = 10
                $dmg = $FighterDamage
                $w2 = 10;20/2
                $xn = $Enemies[$i][1] - $w2
                $xe = $Enemies[$i][1] + $w2
                $yn = $Enemies[$i][2] - $w2
                $ye = $Enemies[$i][2] + $w2

                If ($x >= $xn And $x <= $xe) And ($y >= $yn And $y <= $ye) Then
                    ;$Enemies[$i][0]=0
                    $bDetonate = True
                    $Shots[$iS][0] = 0
                    $Enemies[$i][15] -= $dmg

                    If $Enemies[$i][15] < 0 Then

                        For $an = 1 To 360 Step 45
                            AddShot($Enemies[$i][1], $Enemies[$i][2], $an, $Red_Pen, 1, 2)
                        Next

                        $Enemies[$i][0] = 0
                        $Enemies[$i][1] = 0
                        $Enemies[$i][2] = 0
                        $hsz *= 2
                        Play($Boom)
                        ConsoleWrite('Enemy Destroyed ' & $i & @CRLF)
                    Else
                        ConsoleWrite('Enemy Hit ' & $i & @CRLF)
                    EndIf

                    If $Shots[$iS][6] = 1 Then $PlayerHP += $dmg * ($PlayerDmgToHPRatio + ($Enemies[$i][12] / $PlayerShpToHPRatio))

;~                  Local $br = $Green_Brush

                    If $Shots[$iS][6] = 1 Then
                        AddHit($hsz, $x, $y, $Green_Brush)
                    Else
                        AddHit($hsz, $x, $y, $Red_Brush)
                    EndIf
                    ;ExitLoop
                EndIf
            EndIf
        EndIf
    Next

    If $bDetonate And $Shots[$iS][7] = 1 Then
        $Shots[$iS][0] = 0

        For $an = 1 To 360 Step 30
            AddShot($x, $y, $an, $Shots[$iS][4], 1, $Shots[$iS][6]) ; 2) ; -unknown owner, hurts everone
        Next
    EndIf
EndFunc ;==>ShotCollision

Func Line($x, $y, $w, $a);,$pen=-1)
    Global $Line_x, $Line_y
    ;(x,y) is the origin
    ;w=Hyp, a=Theta
    $a *= $DegToRad; Degrees to Radians
    Local $Opp = -1 * Sin($a) * $w; (Opp/Hyp) x Hyp = Opp, negated to allow conventional angles (45 degrees in QI)
    Local $Adj = Cos($a) * $w;  (Adj/Hyp) x Hyp = Adj
    $Line_x = $x + $Adj
    $Line_y = $y + $Opp
    ;If Not ($pen=-1) Then $tmpPen=$pen

    If Not _GDIPlus_GraphicsDrawLine($gr, $x, $y, $Line_x, $Line_y, $tmpPen) Then
        ConsoleWrite('Line False' & @CRLF)
    EndIf
EndFunc ;==>Line

Func MoveAngle(ByRef $x, ByRef $y, ByRef $a, $dist)
    Local $rA = $a * $DegToRad
    ;$a*=$DegToRad
    $y += -1 * Sin($rA) * $dist
    $x += Cos($rA) * $dist
EndFunc ;==>MoveAngle

Func GUI_Exit()
    $Playing = False
EndFunc ;==>GUI_Exit

Func _CircValue(ByRef $i, $n, $x)
    If $i >= $n And $i <= $x Then Return

    While $i > $x
        Local $dX = $i - $x
        $i = $n + $dX - 1
    WEnd

    While $i < $n
        Local $dn = $n - $i
        $i = $x - $dn
    WEnd
EndFunc ;==>_CircValue
Edited by jaberwocky6669
Posted (edited)

EDIT: To be clearer, I welcome late replies as long as they keep the timeline in mind.

You two realize, of course, that this thread was a year old - of course it's going to have problems with the newer AutoIt versions.

If I have free time I will:

  • Check the Jabberwocky's script
  • Download the new AutoIt
  • Fix the script to work with it

Although my being on dialup may keep me from doing #2 very soon.

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

Posted (edited)

_SoundOpen() returns a 3 element array which you're then tyring to load into one element of an array. That's what it seems to me at least. Also, SoundOpen only accepts one parameter.

Edit: Anyone care to try this and tell me if this works, please? (Download the sound files from the OP if you haven't yet done so.

[snip]

  • At some time the uploaded version of the game got rolled back. (newest had some extra junk, but no fixes) or I forgot to upload it.

  • Your changes to Play() were acceptable because _SoundPlay by default doesn't block it's own playing; However, it does block playing the same sound (by ID) until the previous finished. So, in this case, you can only hear one "shot" while "shot" is playing, even if 5 are being Play()'d. My original "fix" was to detect this condition and use SoundSeek to position the sound at the beginning so that the new Play() call would have an effect. I don't know why, but you've removed that call to SoundSeek, meaning only one shot can play at a time.

  • Your "Static" declaration TSounds looks correct and should work, but for some reason it doesn't work for me. ("shots" are still played within less than 50ms of each other, using a Global to check. This is also most noticeable when a ship explodes and many shots are created at once.)

I only briefly looked over your script, if you changed anything other than Play() and the Sound globals - you will have to point it out for me so that I can comment on it or add it.

That being said, here's my take on your changes, added to my local version

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Misc.au3>
#include <Sound.au3>


Global $Form1, $Label1, $gr, $grb, $gro


Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("StarShooter v2.5", 339, 428, 193, 115)
GUISetOnEvent(-3,'GUI_Exit')
$Label1 = GUICtrlCreateLabel("[Graphics Object]", 1, 0, 335, 394, -1, $WS_EX_STATICEDGE)
GUICtrlSetColor(-1,0x00FF00)
GUICtrlSetBkColor(-1,0x000000)
$StatLab=GUICtrlCreateLabel("",1,394,280,20)
GUICtrlSetOnEvent(-1,'DesiredFPSToggle')
GUICtrlSetColor(-1,0x00FF00)
GUICtrlSetBkColor(-1,0x000000)
$FPSEdit=GUICtrlCreateInput("10",281,394,40,20)
GUICtrlSetTip(-1,'Sets a desired FPS, not that GDI is likely be close to this.')
GUICtrlSetColor(-1,0x00FF00)
GUICtrlSetBkColor(-1,0x000000)
GUICtrlSetState($FPSEdit,$GUI_DISABLE)
$DummyButton=GUICtrlCreateButton(' ',1000,1000,1,1)

#EndRegion ### END Koda GUI section ###



;GDI Setup
$cHWnd=GUICtrlGetHandle($Label1)
$cPos=ControlGetPos($Form1,'',$Label1)
_GDIPlus_Startup()
$gro=_GDIPlus_GraphicsCreateFromHWND($cHWnd)
$grb=_GDIPlus_BitmapCreateFromGraphics($cPos[2],$cPos[3],$gro)
$gr=_GDIPlus_ImageGetGraphicsContext($grb)


;Game Vars
Global $Green_Pen=_GDIPlus_PenCreate(0xFF00FF00)
Global $Red_Pen=_GDIPlus_PenCreate(0xFFFF0000)
Global $Yellow_Pen=_GDIPlus_PenCreate(0xFFFF7F00)
Global $Green_Brush=_GDIPlus_BrushCreateSolid(0xFF00FF00)
Global $Red_Brush=_GDIPlus_BrushCreateSolid(0xFFFF0000)
Global $tmpPen=0
Global $Pi=3.14159
Global $DegToRad=$Pi/180
Global $RadToDeg=180/$Pi
Global $ShipTypeHP[3]=[10,20,40]
Global $Keys[9]   = ['25','27','28','26','20','41','53','44','46']
Global $Player[11] = [100,100,20,90,    0,0,   0,0,  0,0,        0]
Global $PlayerSpeed=10
Global $PlayerTurnR=10
Global $PlayerInput=True
Global $CanFire=True
Global $EnemiesCanFire=True

;$Player[10]=2
Global $PlayerHPRatio=110/$ShipTypeHP[$Player[10]]
Global $PlayerHP=$ShipTypeHP[$Player[10]]*$PlayerHPRatio;9999999 if you want to cheat....
Global $PlayerDmgToHPRatio=0.8
Global $PlayerShpToHPRatio=2

Global $WingFired=0
Global $AIShotDelay=250

Global $ShotW=5
Global $ShotX=99
Global $ShotRange=10; movements, not px
Global $Shots[$ShotX+1][8];0 shot?, 1 x, 2 y, 3 a, 4 pen, 5 moves, 6 owner, 7 type
Global $ShotError=10; degrees
Global $ShotSpeed=$ShotW*3
Global $FighterDamage=6
Global $EnemiesX=49
Global $Enemies[$EnemiesX+1][16]
Global $TargetLines=False
Global $HitsX=99
Global $Hits[$HitsX+1][4]

Global $desired_fps=10
Global $frame_time=1000/$desired_fps
Global $actual_fps
Global $desiredtoggle=True

Global $Anim3_Timer=TimerInit()
Global $AnimationN=0
Global $AnimationI=0
Global $Wins=0
Global $Level=0
Global $Playing=True

Global $Phaser = _SoundOpen(@ScriptDir & '\phaser.wav')
Global $Shot = _SoundOpen(@ScriptDir & '\shot.wav')
Global $Expl = _SoundOpen(@ScriptDir & '\expl.wav')
Global $Boom = _SoundOpen(@ScriptDir & '\boom.wav')




ClearField()
;Game Init
GUISetState(@SW_SHOW)
While $Playing
    Local $fps_timer=TimerInit()
    If $PlayerHP<0 Then
        Play($Boom)
        UpdateScore()
        MsgBox(0,'', 'You have died!')
        $PlayerHP=$ShipTypeHP[$Player[10]]*$PlayerHPRatio
        $Level=0
        ClearField()
        $Anim3_Timer=TimerInit()
    EndIf
    If $PlayerHP>50 And TimerDiff($Anim3_Timer)>60000 Then
        If $AnimationN=0 Then
            $AnimationN=3
            $Anim3_Timer=TimerInit()
        EndIf
    EndIf
    If Not EnemyExists() And $AnimationN=0 Then

        $Level+=1

        Select
            Case $Level<=3
                For $n=1 To $Level
                    AddEnemy(Random(50,$cPos[2]-50,1),Random(50,$cPos[3]-50,1),-1,$Red_Pen,0)
                Next
            Case $Level<=6
                For $n=1 To $Level-3
                    If $n=1 Then
                        AddEnemy(Random(50,$cPos[2]-50,1),Random(50,$cPos[3]-50,1),-1,$Red_Pen,1)
                    Else
                        AddEnemy(Random(50,$cPos[2]-50,1),Random(50,$cPos[3]-50,1),-1,$Red_Pen,0)
                    EndIf
                Next
            Case $Level<=9
                For $n=1 To $Level-6
                    If $n=1 Or $n=3 Then
                        AddEnemy(Random(50,$cPos[2]-50,1),Random(50,$cPos[3]-50,1),-1,$Red_Pen,1)
                    Else
                        AddEnemy(Random(50,$cPos[2]-50,1),Random(50,$cPos[3]-50,1),-1,$Red_Pen,0)
                    EndIf
                Next
            Case $Level<=12
                For $n=1 To $Level-9
                    AddEnemy(Random(50,$cPos[2]-50,1),Random(50,$cPos[3]-50,1),-1,$Red_Pen,1)
                Next
            Case $Level=13
                If Not $AnimationN=0 Then
                    $AnimationI=0
                    $AnimationN=2
                EndIf

            Case $Level=15
                For $i=1 To $Wins+1
                    AddEnemy(Random(50,$cPos[2]-50,1),Random(50,$cPos[3]-50,1),-1,$Red_Pen,2,40)
                Next

            Case $Level=17
                MsgBox(0,'','You won!'&@CRLF&'Continue playing for advanced challenges.')
                ;$PlayerHP=200; hehehe ;)  -  winners benefits.
                $PlayerSpeed*=1.5
                $PlayerTurnR*=1.5
                $FighterDamage*=1.5
                $AIShotDelay/=1.5
                $Level=0
                $Wins+=1
                If $Player[10]<2 Then $Player[10]+=1; yes you get a ship upgrade (visually)
                If $Player[10]=2 Then $Player[2]=40
                $PlayerHP=$ShipTypeHP[$Player[10]]*$PlayerHPRatio
                ClearField()
        EndSelect






        ;If $Level=4 Then $AnimationN=1
    EndIf
    _GDIPlus_GraphicsClear($gr,0xFF000000)
    AnimCheck(); things the user cannot control.
    MoveCheck()
    DrawPlane()
    Local $frame_delay=$frame_time-TimerDiff($fps_timer)
    If $frame_delay>0.5 Then Sleep($frame_delay)
    $actual_fps=1000/TimerDiff($fps_timer)
    ;ConsoleWrite($frame_delay&@CRLF&@TAB&Round($actual_fps)&' fps'&@CRLF)
WEnd

$tmpPen=0
_GDIPlus_PenDispose($Yellow_Pen)
_GDIPlus_PenDispose($Red_Pen)
_GDIPlus_PenDispose($Green_Pen)
_GDIPlus_BrushDispose($Red_Brush)
_GDIPlus_BrushDispose($Green_Brush)
_GDIPlus_GraphicsDispose($gr)
_GDIPlus_BitmapDispose($grb)
_GDIPlus_GraphicsDispose($gro)
_GDIPlus_Shutdown()
_SoundClose($Phaser)
_SoundClose($Shot)
_SoundClose($Expl)
_SoundClose($Boom)
Exit




Func DesiredFPSToggle()
    Global $desiredtoggle
    Switch $desiredtoggle
        Case True
            GUICtrlSetState($FPSEdit,$GUI_ENABLE+$GUI_FOCUS)
            $desiredtoggle=False
        Case Else
            GUICtrlSetState($FPSEdit,$GUI_DISABLE+$GUI_NOFOCUS)
            GUICtrlSetState($DummyButton,$GUI_FOCUS)
            $desiredtoggle=True
    EndSwitch
EndFunc


Func Play(ByRef $sound)
    Global $Tsound
    Switch _SoundStatus($sound)
        Case 'not ready'
            Return
        Case 'playing'
            Switch $sound[0]
                Case $Phaser[0]
                Case $Shot[0], $Expl[0]
                    If TimerDiff($Tsound) < 50 Then Return
                    _SoundSeek($sound, 0, 0, 0);replay the sound, otherwise it will just complete the current sound.
            EndSwitch
    EndSwitch
    _SoundPlay($sound)
    $Tsound = TimerInit()
EndFunc   ;==>Play


Func DrawPlane()
    $tmpPen=$Green_Pen
    If $PlayerHP>100 Then _GDIPlus_GraphicsDrawEllipse($gr,$Player[0]-($Player[2]*0.5+5),$Player[1]-($Player[2]*0.5+5),$Player[2]+10,$Player[2]+10,$tmpPen)
            Ship($Player[10],$Player[0],$Player[1],$Player[2],$Player[3],$Player[4],$Player[5],$Player[6],$Player[7],$Player[8],$Player[9])
    For $i=0 To $ShotX
        If $Shots[$i][0]=1 Then
            If ($Shots[$i][7]=0 And $Shots[$i][5]>$ShotRange) Then ;Or $Shots[$i][1]<-5 Or $Shots[$i][1]>$cPos[2]+5 Or $Shots[$i][2]<-5 Or $Shots[$i][2]>$cPos[3]+5 Then
                ;ConsoleWrite('Del Shot'&@CRLF)
                $Shots[$i][0]=0
                ContinueLoop
            EndIf
            _CircValue($Shots[$i][1],0,$cPos[2])
            _CircValue($Shots[$i][2],0,$cPos[3])


            $tmpPen=$Shots[$i][4]
            ShotCollision($i, $Shots[$i][1],$Shots[$i][2])
            ;Shot(Byref $type,Byref $x,Byref $y,Byref $a)
            If $Shots[$i][0]=1 Then Shot($Shots[$i][7],$Shots[$i][1],$Shots[$i][2],$Shots[$i][3])
            MoveAngle($Shots[$i][1], $Shots[$i][2], $Shots[$i][3], $ShotSpeed)
            $Shots[$i][5]+=1
        EndIf
    Next
    For $i=0 To $HitsX
        If $Hits[$i][0]>0 Then
            _GDIPlus_GraphicsFillEllipse($gr,$Hits[$i][1],$Hits[$i][2],$Hits[$i][0],$Hits[$i][0],$Hits[$i][3])
            $Hits[$i][0]-=2
        EndIf
    Next


    For $i=0 To $EnemiesX
        If $Enemies[$i][0]=1 Then

#cs
            If $Enemies[$i][1]<-50 Or $Enemies[$i][1]>$cPos[2]+50 Or $Enemies[$i][2]<-50 Or $Enemies[$i][2]>$cPos[3]+50 Then
                ;ConsoleWrite('Del Shot'&@CRLF)
                $Enemies[$i][0]=0
                ContinueLoop
            EndIf
#ce
            _CircValue($Enemies[$i][1],0,$cPos[2])
            _CircValue($Enemies[$i][2],0,$cPos[3])


            $tmpPen=$Enemies[$i][5]
            Ship($Enemies[$i][12],$Enemies[$i][1],$Enemies[$i][2],$Enemies[$i][3],$Enemies[$i][4],$Enemies[$i][6],$Enemies[$i][7],$Enemies[$i][8],$Enemies[$i][9],$Enemies[$i][10],$Enemies[$i][11])
            EMove($i)
        EndIf
    Next

    UpdateScore()

    _GDIPlus_GraphicsDrawImageRect($gro, $grb, 0, 0, $cpos[2], $cpos[3]) ;copy to bitmap
EndFunc


Func UpdateScore($Forced=False)
    Global $UpTimer
    If $Forced Or TimerDiff($UpTimer)>500 Then
        GUICtrlSetData($StatLab,'Health: '&Int($PlayerHP)&'/100   -   Level: '&$Level&'    -  FPS: '&Round($actual_fps)&'  -  Desired FPS: ')
        $desired_fps=GUICtrlRead($FPSEdit)
        $frame_time=1000/$desired_fps
        $UpTimer=TimerInit()
    EndIf
EndFunc






Func EnemyExists()
    For $i=0 To $EnemiesX
        If $Enemies[$i][0]=1 Then Return True
    Next
    Return False
EndFunc

Func ClearField()
    For $i=0 To $EnemiesX
        $Enemies[$i][0]=0
    Next
    For $i=0 To $ShotX
        $Shots[$i][0]=0
    Next
    For $i=0 To $HitsX
        ;ConsoleWrite($i&'/'&$HitsX&@CRLF)
        $Hits[$i][0]=0
    Next
    $AnimationN=0
    $AnimationI=0
EndFunc


Func AnimCheck()
    Switch $AnimationN
        Case 0

        Case 1
            $CanFire=False
            $PlayerInput=False
            If $AnimationI<60 Then
                $Player[3]+=$AnimationI
            Else
                $Player[3]+=(100-$AnimationI)
                If (100-$AnimationI)<=0 Then
                    $AnimationN=0
                    $PlayerInput=True
                    $CanFire=True
                    $AnimationI=0
                    Return
                EndIf
            EndIf
            Switch $AnimationI
                Case 53
                    $CanFire=True
                    For $i=1 To 360 Step 5
                        AddShot($Player[0],$Player[1],$i,$Green_Pen,1,1)
                    Next
                    $CanFire=False
            EndSwitch
            $AnimationI+=1
        Case 2; placeholder animation for final battle (nonexistant level 14)
            $Level=14

            $AnimationN=0
            $AnimationI=0
        Case 3
            Global $Anim3_X, $Anim3_Y, $Anim3_S, $Anim3_A
            If $AnimationI=1 Then
                $Anim3_Y=Random(50,$cpos[3]-50,1)
                Switch (Random(1,100)<50)
                    Case True
                        $Anim3_A=0
                        $Anim3_X=0
                        $Anim3_S=5
                    Case False
                        $Anim3_A=180
                        $Anim3_X=$cPos[2]
                        $Anim3_S=-5
                EndSwitch
            EndIf


            If $AnimationI>1 And $AnimationI<161 Then
                Local $type=2
                $Anim3_X+=$Anim3_S
                Local $y=$Anim3_Y
                Local $w=40
                Local $wx=60
                Local $w2=30
                Local $a=180
                Local $Head_x,$Head_y,$WingL_x,$WingL_y,$WingR_x,$WingR_y

                Local $ttmpPen=$tmpPen
                $tmpPen=$Red_Pen
                _GDIPlus_GraphicsDrawEllipse($gr,$Anim3_X-$w2,$y-$w2,$wx,$wx,$Yellow_Pen)
                Ship($type, $Anim3_X, $y, $w,$Anim3_A,   $Head_x, $Head_y, $WingL_x, $WingL_y, $WingR_x,$WingR_y)

                Global $Anim3_T
                If $Anim3_X>5 And $Anim3_X<$cPos[2]-5 And TimerDiff($Anim3_T)>3000 Then
                    Local $pX=$Player[0]
                    Local $pY=$Player[1]
                    Local $dX=$pX-$Anim3_X
                    Local $dY=$pY-$y
                    Local $Hyp=($dX^2)+($dY^2)
                    Local $a=ATan($dX/$dY)*$RadToDeg + 90
                    If $dY>=0 Then $a+=180
                    _CircValue($a,0,360)
                    AddShot($Anim3_X,$y,$a,$Red_Pen,1,2,1)
                    $Anim3_T=TimerInit()
                EndIf

            EndIf
            If $AnimationI>1 And ($AnimationI=160 Or $Anim3_X<-50 Or $Anim3_X>$cpos[2]+50) Then
                $AnimationN=0
                $AnimationI=0
                Return
            EndIf
            $AnimationI+=1
    EndSwitch
EndFunc
Func MoveCheck()
    If Not $PlayerInput Then Return
    ;Ship Angle changes
    If _IsPressed($Keys[5]) Then $AnimationN=2
    If _IsPressed($Keys[6]) Then $AnimationN=3
    If _IsPressed($Keys[7]) Then $AnimationN=1
    If _IsPressed($Keys[0]) Then $Player[3]+=$PlayerTurnR
    If _IsPressed($Keys[1]) Then $Player[3]-=$PlayerTurnR

    ;Ship Movement
    Local $AMoveS=0
    If _IsPressed($Keys[2]) Then $AMoveS=-1; reverse - on a spaceship!? I think not.
    If _IsPressed($Keys[3]) Then $AMoveS= 1
    If $AMoveS<>0 Then
        MoveAngle($Player[0], $Player[1], $Player[3], $PlayerSpeed*$AMoveS)
        _CircValue($Player[0],0,$cPos[2])
        _CircValue($Player[1],0,$cPos[3])
        ;iLimit($Player[0],0,$cPos[2])
        ;iLimit($Player[1],0,$cPos[3])
    EndIf
    Local $hasFired=False
    Local $firemode=0
    If _IsPressed($Keys[4]) Then $hasFired=True
    If _IsPressed($Keys[8]) Then
        $firemode=1
        $hasFired=True
    EndIf
    If $hasFired Then
        Local $sX,$sY
        Switch $WingFired
            Case 0
                $WingFired=1
                $sX=$Player[8]
                $sY=$Player[9]
                ;AddShot($x,$y,$a,$pen,$n=1, $owner=0, $type=0)
                AddShot($sX,$sY,$Player[3]+5,$Green_Pen,1,1,$firemode );  ,1)
            Case 1
                $WingFired=0
                $sX=$Player[6]
                $sY=$Player[7]
                AddShot($sX,$sY,$Player[3]-5,$Green_Pen,1,1,$firemode);   ,1)
        EndSwitch
    EndIf
EndFunc

Func iLimit(ByRef $i,$n,$x)
    If $i<$n Then $i=$n
    If $i>$x Then $i=$x
EndFunc



Func EMove($iE)
    If $Enemies[$iE][0]=0 Then Return

    Local $pX=$Player[0]
    Local $pY=$Player[1]

    ;limit only if we want the units to turn away from the edge
    ;iLimit($pX,50,$cPos[2]-50)
    ;iLimit($pY,50,$cPos[3]-50)

    Local $dX=$pX-$Enemies[$iE][1]
    Local $dY=$pY-$Enemies[$iE][2]
    Local $Hyp=($dX^2)+($dY^2)
    Local $a=ATan($dX/$dY)*$RadToDeg + 90
    Local $bHeavy=($Enemies[$iE][12]==1)
    Local $bDread=($Enemies[$iE][12]==2)


    Local $espd, $turn


    If $bHeavy Or $bDread Then
        $tmpPen=$Yellow_Pen; shots are yellow/orange for higher damage
        If $bHeavy Then
            $espd=$PlayerSpeed
            $turn=$PlayerTurnR
        Else; bDread
            $espd=$PlayerSpeed/1.5;*3.5
            $turn=$PlayerTurnR
        EndIf
    Else
        $espd=$PlayerSpeed*0.8
        $turn=$PlayerTurnR*2
    EndIf



    If $dY>=0 Then $a+=180

    If $TargetLines Then Line($Enemies[$iE][1],$Enemies[$iE][2],100,$a); Targetting Line

    Local $dist=Sqrt(($dX^2) + ($dy^2))

    _CircValue($Enemies[$iE][4],0,359)
    _CircValue($a,0,359)

    Local $sa1,$sa2
    SweepDistance_Short($sa1,$a,$Enemies[$iE][4]-$turn); originally -1, +1
    SweepDistance_Short($sa2,$a,$Enemies[$iE][4]+$turn)

    Local $saN
    Local $saSign=1
    Select
        Case $sa1<=$sa2
            $saN=$sa1
            $saSign=-1
        Case $sa2<$sa1
            $saN=$sa2
    EndSelect

    $sa1=0
    $sa2=0


    ;ConsoleWrite('Current Angle: '&$Enemies[$iE][4]&@CRLF)
    ;ConsoleWrite('Desired Angle: '&$a&@CRLF)
    ;ConsoleWrite('Shortest Dist: '&SweepDistance_Short($a,$Enemies[$iE][4])&@CRLF)
    ;ConsoleWrite($sa1&' '&$sa2&@CRLF)

    Local $phRangeP=($Player[10]+1)*30
    Local $phRangeE=($Enemies[$iE][12]+1)*30
    Local $bFirePhasersE=True
    Local $inRange=($dist<=($ShotRange*$ShotW)*3.5)


    If $saN<45 Then
        $bFirePhasersE=False
    EndIf


    Local $FireShots=False
    If $CanFire Then
        $FireShots=True
        Local $dmg
        Local $hsz
        If $dist<=$phRangeP Then
            Global $PPhaserTimer
            ;;If True Then;TimerDiff($PPhaserTimer)>($AIShotDelay/2) Then
                $hsz=10
                $w2=10;20/2
                $xn=$Enemies[$iE][1]-$w2
                $xe=$Enemies[$iE][1]+$w2
                $yn=$Enemies[$iE][2]-$w2
                $ye=$Enemies[$iE][2]+$w2

                $x=$Enemies[$iE][1]
                $y=$Enemies[$iE][2]

                Play($Phaser)
                _GDIPlus_GraphicsDrawLine($gr,$x,$y,$Player[0],$Player[1],$Green_Pen)
                $dmg=$Enemies[$iE][15]/(20*(3-$Player[10]))
                If $dmg<0.5 Then $dmg=0.5
                $Enemies[$iE][15]-=$dmg
                If $Enemies[$iE][15]<0 Then
                    For $an=1 To 360 Step 45
                        AddShot($Enemies[$iE][1],$Enemies[$iE][2],$an,$Red_Pen,1,2)
                    Next
                    $Enemies[$iE][0]=0
                    $Enemies[$iE][1]=0
                    $Enemies[$iE][2]=0
                    $hsz*=2
                    Play($Boom)
                EndIf
                $PlayerHP+=$dmg*($PlayerDmgToHPRatio+($Enemies[$iE][12]/$PlayerShpToHPRatio))
                AddHit($hsz,$x,$y,$Green_Brush)

                $PPhaserTimer=TimerInit()


            ;EndIf
        EndIf
        If $Enemies[$iE][0]=0 Then Return
        If $EnemiesCanFire And $bFirePhasersE And $dist<=$phRangeE Then
            ;If TimerDiff($Enemies[$iE][13])>($AIShotDelay/2) Then
                    $hsz=10
                    $w2=$Player[2]/2
                    $xn=$Player[0]-$w2
                    $xe=$Player[0]+$w2
                    $yn=$Player[1]-$w2
                    $ye=$Player[1]+$w2

                    $x=$Player[0]
                    $y=$Player[1]




                    Play($Phaser)
                    $dmg=$PlayerHP/(20*(3-$Enemies[$iE][12]))
                    If $dmg<0.5 Then $dmg=0.5
                    _GDIPlus_GraphicsDrawLine($gr,$Enemies[$iE][1],$Enemies[$iE][2],$x,$y,$tmpPen)
                    $PlayerHP-=$dmg
                    $FireShots=False
                    $Enemies[$iE][13]=TimerInit()
                    If $PlayerHP<0 Then $hsz*=2

                    AddHit($hsz,$x,$y,$Red_Brush)
                    $FireShots=False
                ;EndIf
            ;EndIf
        EndIf
    EndIf

    Local $bTurn=False
    Local $bMove=True

    Switch $Enemies[$iE][12]
        Case 2
            If $dist>90 Then
                If $saN>10 Then
                    $bTurn=True
                    $bMove=False
                    $FireShots=True
                EndIf
                If $saN<=90 Then
                    $FireShots=True
                    $bMove=True
                EndIf
            Else
                $bTurn=False
                $bMove=True
                $FireShots=True
            EndIf
        Case 1
            If ($saN>35 And $dist>30) Then
                $bTurn=True
                $FireShots=False
                $espd*=0.5
            ;Else
            ;   If $inRange Then $bMove=False
            EndIf
        Case 0
            If ($saN>35 And $dist>30) Then
                $bTurn=True
                $FireShots=False
            EndIf
    EndSwitch

;add this only to force enemies to move forward only back onto the field when at the edge
#cs
    If $Enemies[$iE][1]<0 Or $Enemies[$iE][1]>$cPos[2] Or $Enemies[$iE][2]<0 Or $Enemies[$iE][2]>$cPos[3] Then
        If $saN>10 Then
            $bTurn=True
            $bMove=False
        EndIf
    EndIf
#ce



    If $bTurn Then
        iLimit($saN,0,$turn)
        $Enemies[$iE][4]+=$saSign*$saN
    EndIf

    if $CanFire And $FireShots And $EnemiesCanFire Then
        Local $tmpShipFire=False
        Local $firetype=0
        If TimerDiff($Enemies[$iE][13])>$AIShotDelay Then
            If $bDread Then
                If Random(1,100,1)<=10 Then
                    $firetype=1
                    $tmpShipFire=True
                Else
                    If (Not $inRange) Then $Enemies[$iE][13]=TimerInit()
                EndIf
            EndIf
            If (Not $tmpShipFire) And $inRange Then $tmpShipFire=True
            If $tmpShipFire Then
                Switch $Enemies[$iE][14]; your enemies' cannons are much less efficient and sometimes jam. ;)
                    Case 0
                        AddShot($Enemies[$iE][8],$Enemies[$iE][9],$a,$tmpPen,1,0,$firetype);$Enemies[$iE][4]
                        $Enemies[$iE][14]=1
                    Case 1
                        AddShot($Enemies[$iE][10],$Enemies[$iE][11],$a,$tmpPen,1,0,$firetype)
                        $Enemies[$iE][14]=0
                EndSwitch
                $Enemies[$iE][13]=TimerInit()
            EndIf
        EndIf
    EndIf

    If $bMove Then MoveAngle($Enemies[$iE][1], $Enemies[$iE][2], $Enemies[$iE][4],$espd)

EndFunc

Func SweepDistance_Short(Byref $angle, $a1,$a2)
    $angle = Mod((Abs($a1 - $a2)),360)
    If $angle>180 Then $angle = 360 - $angle
EndFunc




Func AddEnemy($x,$y,$a,$pen,$type=0,$w=20,$hp=-1)
    if $a=-1 Then $a=Random(1,360,0)
    For $i=0 To $EnemiesX
        If $Enemies[$i][0]=0 Then
            $Enemies[$i][0]=1
            $Enemies[$i][1]=$x
            $Enemies[$i][2]=$y
            $Enemies[$i][3]=$w;w
            $Enemies[$i][4]=$a
            $Enemies[$i][5]=$pen
            For $iii=6 To 11
                $Enemies[$i][$iii]=0
            Next
            $Enemies[$i][12]=$type
            $Enemies[$i][13]=0
            $Enemies[$i][14]=0
            If $hp=-1 Then
                $Enemies[$i][15]=$ShipTypeHP[$type]
            Else
                $Enemies[$i][15]=$hp
            EndIf

            Return $i
        EndIf
    Next
    Return -1
EndFunc

Func AddHit($hsz,$x,$y,$brush)
    _CircValue($x,0,$cPos[2])
    _CircValue($y,0,$cPos[3])
    For $ii=0 To $HitsX
        If $Hits[$ii][0]<=0 Then
            $Hits[$ii][0]=$hsz
            $Hits[$ii][1]=$x
            $Hits[$ii][2]=$y
            $Hits[$ii][3]=$brush
            Play($Expl)
            ExitLoop
        EndIf
    Next
EndFunc


Func AddShot($x,$y,$a,$pen,$n=1, $owner=0, $type=0)
    If Not $CanFire Then Return
    For $ii=1 To $n
        For $i=0 To $ShotX
            If $Shots[$i][0]=0 Then
                ;ConsoleWrite('Add Shot'&@CRLF)
                $Shots[$i][0]=1
                $Shots[$i][1]=$x
                $Shots[$i][2]=$y
                $Shots[$i][3]=$a+Random(-1*$ShotError,$ShotError,1)
                $Shots[$i][4]=$pen
                $Shots[$i][5]=0
                $Shots[$i][6]=$owner
                $Shots[$i][7]=$type
                ExitLoop
            EndIf
        Next
    Next
    Play($Shot)
EndFunc


Func Shot(Byref $type,Byref $x,Byref $y, Byref $a)
    Global $ShotW
    Switch $type
        Case 0
            Line($x,$y,$ShotW,$a)
        Case 1
            For $i=1 To 360 Step 45
                Line($x,$y,$ShotW,$i)
            Next
    EndSwitch
EndFunc
Func Ship(Byref $type, Byref $x, Byref $y,Byref $w,Byref $a,  ByRef $Head_x,ByRef $Head_y,ByRef $WingL_x,ByRef $WingL_y,ByRef $WingR_x,ByRef $WingR_y)
    Global $Line_x, $Line_y
    Local $w2=$w*0.5
    Local $w4=$w2*0.5
    Local $w8=$w4*0.5

    Switch $type
        Case 0
            Line($x,$y,$w2,$a)     ;      |--->  head
                $Head_x=$Line_x
                $Head_y=$Line_y
            Line($x,$y,$w2,$a+180) ; <---|       tail

            Line($x,$y,$w2,$a+90);       +^      wing L
                $WingL_x=$Line_x
                $WingL_y=$Line_y
            Line($x,$y,$w2,$a-90);       +,      wing R
                $WingR_x=$Line_x
                $WingR_y=$Line_y


            Line($Head_x,$Head_y,$w2,$a+153) ;--\  nose
            Line($Head_x,$Head_y,$w2,$a-153) ;--/

            Line($WingL_x,$WingL_y,$w4,$a)
                $WingL_x=$Line_x
                $WingL_y=$Line_y
            Line($WingR_x,$WingR_y,$w4,$a)
                $WingR_x=$Line_x
                $WingR_y=$Line_y
        Case 1
            Line($x,$y,$w2,$a)     ;      |--->  head
                $Head_x=$Line_x
                $Head_y=$Line_y
            Line($x,$y,$w2,$a+135)
                $WingL_x=$Line_x
                $WingL_y=$Line_y
            Line($x,$y,$w2,$a-135)
                $WingR_x=$Line_x
                $WingR_y=$Line_y
            _GDIPlus_GraphicsDrawEllipse($gr,$x-$w2,$y-$w2,$w,$w,$tmpPen)
            Line($WingL_x,$WingL_y,$w,$a)
                $WingL_x=$Line_x
                $WingL_y=$Line_y
            Line($WingR_x,$WingR_y,$w,$a)
                $WingR_x=$Line_x
                $WingR_y=$Line_y
        Case 2
            Line($x,$y,$w2,$a)     ;      |--->  head
                $Head_x=$Line_x
                $Head_y=$Line_y
            Line($x,$y,$w2,$a+180) ; <---|       tail
                Local $Tail_x=$Line_x,$Tail_y=$Line_y

            Line($Head_x,$Head_y,$w2+$w8,$a+153) ;--\  nose
            Line($Head_x,$Head_y,$w2+$w8,$a-153) ;--/

            Line($x,$y,$w2-$w8,$a+45);       +^      wing L
                $WingL_x=$Line_x
                $WingL_y=$Line_y
            Line($x,$y,$w2-$w8,$a-45);       +,      wing R
                $WingR_x=$Line_x
                $WingR_y=$Line_y



            Line($WingR_x,$WingR_y,$w2,$a-180)
            Line($WingR_x,$WingR_y,$w8,$a-90)
            Line($Line_x,$Line_y,$w2,$a-180)
            Local $lax=$Line_x,$lay=$Line_y
            Line($Line_x,$Line_y,$w4,$a-180)


            Line($WingL_x,$WingL_y,$w2,$a-180)
            Line($WingL_x,$WingL_y,$w8,$a+90)
            Line($Line_x,$Line_y,$w2,$a-180)
            _GDIPlus_GraphicsDrawLine($gr,$Line_x,$Line_y,$Tail_x,$Tail_y,$tmpPen)
            _GDIPlus_GraphicsDrawLine($gr,$lax,$lay,$Tail_x,$Tail_y,$tmpPen)
            Line($Line_x,$Line_y,$w4,$a-180)

            Line($WingL_x,$WingL_y,$w4,$a)
            $WingL_x=$Line_x
            $WingL_y=$Line_y
            Line($WingR_x,$WingR_y,$w4,$a)
            $WingR_x=$Line_x
            $WingR_y=$Line_y
    EndSwitch
EndFunc
Func ShotCollision(Byref $iS, Byref $x, Byref $y)
    If $Shots[$iS][0]=0 Then Return
    Local $pen=$Shots[$iS][4]
    Local $bDetonate=False

    ; don't modify this for cross-screen support, torpedos need to be limited by the window to detonate sooner
    If $x<10 Or $x>$cPos[2]-10 Or $y<10 Or $y>$cPos[3]-10 Then $bDetonate=True

    For $i=-1 To $EnemiesX
        Local $w2
        Local $xn, $xe, $yn, $ye




        If $i=-1 Then
            If $Shots[$iS][6]=1 Then ContinueLoop
            $w2=$Player[2]/2
            $xn=$Player[0]-$w2
            $xe=$Player[0]+$w2
            $yn=$Player[1]-$w2
            $ye=$Player[1]+$w2



            If ($x>=$xn And $x<=$xe) And ($y>=$yn And $y<=$ye) Then
                $bDetonate=True
                $Shots[$iS][0]=0
                ;ConsoleWrite('Player Hit'&@CRLF)

                Local $hsz=10

                Local $dmg=$FighterDamage
                If $pen=$Yellow_Pen Then
                    $hsz*=1.5
                    $dmg*=2
                EndIf

                If $PlayerHP>100 Then
                    $hsz*=0.5
                    $PlayerHP-=$dmg*0.25; shielded
                Else
                    $PlayerHP-=$dmg
                EndIf

                AddHit($hsz,$x,$y,$Red_Brush)

                ExitLoop
            EndIf
        Else
            If $Shots[$iS][6]=0 Then ExitLoop
            If $Enemies[$i][0]=1 Then
                Local $hsz=10
                Local $dmg=$FighterDamage
                $w2=10;20/2
                $xn=$Enemies[$i][1]-$w2
                $xe=$Enemies[$i][1]+$w2
                $yn=$Enemies[$i][2]-$w2
                $ye=$Enemies[$i][2]+$w2
                If ($x>=$xn And $x<=$xe) And ($y>=$yn And $y<=$ye) Then
                    ;$Enemies[$i][0]=0
                    $bDetonate=True

                    $Shots[$iS][0]=0
                    $Enemies[$i][15]-=$dmg
                    If $Enemies[$i][15]<0 Then
                        For $an=1 To 360 Step 45
                            AddShot($Enemies[$i][1],$Enemies[$i][2],$an,$Red_Pen,1,2)
                        Next
                        $Enemies[$i][0]=0
                        $Enemies[$i][1]=0
                        $Enemies[$i][2]=0

                        $hsz*=2
                        Play($Boom)
                        ConsoleWrite('Enemy Destroyed '&$i&@CRLF)
                    Else
                        ConsoleWrite('Enemy Hit '&$i&@CRLF)
                    EndIf
                    If $Shots[$iS][6]=1 Then $PlayerHP+=$dmg*($PlayerDmgToHPRatio+($Enemies[$i][12]/$PlayerShpToHPRatio))

                    Local $br=$Green_Brush

                    If $Shots[$iS][6]=1 Then
                        AddHit($hsz,$x,$y,$Green_Brush)
                    Else
                        AddHit($hsz,$x,$y,$Red_Brush)
                    EndIf
                    ;ExitLoop
                EndIf
            EndIf
        EndIf
    Next

    If $bDetonate And $Shots[$iS][7]=1 Then
        $Shots[$iS][0]=0
        For $an=1 To 360 Step 30
            AddShot($x,$y,$an,$Shots[$iS][4],1,$Shots[$iS][6]) ;  2) ; -unknown owner, hurts everone
        Next
    EndIf
EndFunc


Func Line($x,$y,$w,$a);,$pen=-1)
    Global $Line_x, $Line_y
    ;(x,y) is the origin
    ;w=Hyp, a=Theta
    $a*=$DegToRad; Degrees to Radians
    Local $Opp=-1*Sin($a)*$w;   (Opp/Hyp) x Hyp = Opp, negated to allow conventional angles (45 degrees in QI)
    Local $Adj=Cos($a)*$w;      (Adj/Hyp) x Hyp = Adj
    $Line_x=$x+$Adj
    $Line_y=$y+$Opp
    ;If Not ($pen=-1) Then $tmpPen=$pen
    If Not _GDIPlus_GraphicsDrawLine($gr,$x,$y,$Line_x,$Line_y,$tmpPen) Then
        ConsoleWrite('Line False'&@CRLF)
    EndIf
EndFunc


Func MoveAngle(ByRef $x, ByRef $y, ByRef $a, $dist)
    Local $rA=$a*$DegToRad
    ;$a*=$DegToRad
    $y+=-1*Sin($rA)*$dist
    $x+=   Cos($rA)*$dist
EndFunc


Func GUI_Exit()
    $Playing=False
EndFunc


Func _CircValue(Byref $i,$n,$x)
    If $i>=$n And $i<=$x Then Return
    While $i>$x
        $dx=$i-$x
        $i=$n+$dx-1
    WEnd
    While $i<$n
        $dn=$n-$i
        $i=$x-$dn
    WEnd
EndFunc

Note: only tested on AutoIt 3.3.2.0 at this time, feel free to test on other versions.

EDIT: ZOMG post formatting messed up - FIXED!

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

  • 7 months later...
Posted

Impressive! I'm jealous :x

I'm a compulsive poster. When I post something, come to read it at least 5 minutes later after the posting, because I will edit it. I edited even this signature a few minutes later after I wrote it.

Posted (edited)

Since then, I've been working on this unnamed game to replace StarShooter:
gg2y.th.png

larger: http://imageshack.us/photo/my-images/824/gg2y.png/

I'd share it here, but It's not written in AutoIt (C++ and uses DX9) and I haven't decided if it's open-source yet.
I could share the executable, but nobody is going to take that on faith.

Edit: fixed the StarShooter screenshot on the first post; free host seems to be having some issues.

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

Posted (edited)

I'd take it on faith from someone who's been here for 3 years with no criminal record when the screenshot looks interesting...

Okay then, here it is for anyone who wants to try it...

(Reminder to everyone else: see my previous post before asking what this is)

gg2_rel4_bin.zip

Unlike Starshooter, where controls change your movement, GG2's controls apply acceleration (read: thrust). Collisions from weapon-fire and one specific weapon can also apply acceleration. Projectile objects have values for bump force and bump damage. Asteroids have health and can be destroyed and/or broken into smaller asteroids with enough damage.

Also unlike Starshooter, this game has no levels or points yet, it is basically a test-level currently. There is a 300px game area included outside of the viewing area, if anything gets outside of that, it dies instantly in this test. If you die, there is no fancy message in this test - your health/shields/energy bars will simply disappear.

There is an overarching Faction and Association system applied to all ships determining how different factions view each other and interact. In this test there are two Federation fighters, if you attack one you will be associated as an Enemy by the Federation and will be attacked by both. Asteroids, for one, are marked as enemy projectiles to everyone - only enemy ships will garner more attention. (yes, enemy projectiles in absence of enemies can and will be shot down)

Controls

  • Arrow Up/Down - Accelerates your ship forward or backward (rel: facing angle)
  • Arrow Left/Right - Changes which direction you're facing.
  • Holding Spacebar - Deaccelerates your ship.
  • Enter - Fires a plasma shot (primary weapon for the test)
  • Holding Shift - Changes your firing angle to 180-degrees from facing angle for testing.
  • '1' - Enables debug mode showing drawing dest. rects and bounding circles.
  • '2' - Switch debug display mode
  • '3' - Fires the mining laser
  • '4' - Fires the plasma bomb
  • '5' - Lays a space mine
  • '6' - Fires the tractor beam (uses negative bump force to attract)
  • '9' - Inflicts large amounts of damage on your ship for testing.
  • Escape - Quit.

Notes: Bounding geometry was quick and dirty - it is very incorrect for the Mining Laser and Tractor Beam.

Technical:

There are two executables: GG2.exe and GG2_alt.exe; the first one links to d3dx9_41.dll (used in the SDK lib files), the second links to d3dx9.dll (seen alternatively other places - including one tester on WINE).

Written in C++ with MinGW and the DirectX9 Devpak (SDK is incompatible with MinGW AFAIK), compiled with G++.

The program will need appropriate access to files in it's directory/subdirs to read the Dat/*.projectile structure files and the Image files.

Most of the images suck because I didn't have time to do anything in GIMP - most are just Paint drawings, the explosions and a couple things were retouched a little. There are also alot of unused concept images present.

Can't think of anything that I forgot yet...

Edit: what? the name GG2? Well, before Starshooter was done, something like it was written in AutoIt which was never named aside from GraphicsGame; it was worse than Starshooter by far. This doesn't have a name either, so ... GG2.

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

Posted (edited)

I can't find the dll in my sdks (7.1) so I'm not sure where I'm supposed to get that from...

I'll assume you meant the one I mentioned (d3dx9_41.dll)

The d3dx9_41.dll was supposed to be standard with the newer DirectX 9.0c redistributables. Link.

dxwebsetup is here if you need it.

I'm not sure why you wouldn't have it...

If all else fails, I can just supply it with the executable I guess. Or not, seeing as mine is 4MB and I'm on dialup.

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

Posted (edited)

Very smooth stuff :x I knew it would be good to download :shifty:

Glad you liked it. Let me know if you notice any bugs or optionally have any ideas that you would like contribute to GG2.

Off-topic:

Still debating with myself what I want to do with it and whether to make it free/open-source or not. :nuke:

I hadn't really planned far enough ahead on whether it would be freeware in the end or not; I like source code collaboration and feedback also, but I can't have it both closed and collaborative at the same time on a small project... No idea what the success rate on low-end game monetization is; if it's terribly low (which it probably is) I might be more persuaded to just make it F/OSS.

I've never actually licensed any of my software for-sale before either, so I don't know anything about the topic aside from required programming.

The drawback with making it F/OSS (read: hobbyware) will be that it will get less attention and possibly be discontinued/backburnered for real-world involvement.

I guess I could always go with a donationware model :P) , not that I have any experience with that either.

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...