You are a courier carrying products between facilities on either side of a multi-unmarked-lane highway. There are no traffic lights, traffic can flow in either direction in any lane, and when attempting to cut across the traffic to get to the other side (left edge<>right edge) the courier can start and exit at any point along the highway. The load the courier has to deliver between the facilities increases every four trips. You can only stop (if required) momentarily in a lane, or across a couple of lanes if you are carrying a heavier load. If you have a crash in any four trip sequence, you have to start that set of trips again with a fresh load.
The goal is to make all trips in as short a time as possible, with no crashes. Use the arrow keys for 'driving' the courier vehicle. Under the 'Initialize' procedure, you can vary the starting Y position and 'step size' (which determines speed) for each of the 'vehicles' on the highway to make the game easier or harder. With the current values, the best I could manage is shown in the screenshot
I'm not a gamer, but it seems to test one's pattern detection ability, reflexes and patience (go easy on the arrow keys if you still want them working after this )
Issue: When I tried the game on two different machines with identical initial values, the 'traffic' appeared to go faster on one machine than the other, such that I've yet to complete the game with no crashes on the 'faster' one. I'd be grateful if you might be able to advise what could be causing this - as you can see, the 'TimerBalls' procedure using Elapsedmilliseconds() which is called in its own thread, is updating the position values of the 'vehicles'.
Any other suggestions/code changes to improve the game also gratefully accepted.
Code: Select all
;***"Dodgy Delivery" Game***
Enumeration
#Text_TimeTrip
#Text_Collisions
#Text_FirstSetTrips
#Text_SecondSetTrips
#Text_ThirdSetTrips
#Text_FourthSetTrips
#Button_Reset
EndEnumeration
Global Start
Global TimerState
Global GotToTheEnd
Global GotToTheStart
Global HitCounter
Global TimerBallsEnable = #True
Global CollisionCounter = 0
Global CountdownTimer
Global CountdownTimerAddFlag = #False
Global CountdownTextPersist = #False
Global GameOverTextPersist = #False
Global TheX
Global TheY
Global Value
Global TheStep
Global Value1
Global TheStep1
Global Value2
Global TheStep2
Global Value3
Global TheStep3
Global Value4
Global TheStep4
Global Value5
Global TheStep5
Global Value6
Global TheStep6
Global Value7
Global TheStep7
Global Value8
Global TheStep8
Global Value9
Global TheStep9
Global Value10
Global TheStep10
Global Value11
Global TheStep11
Global Value12
Global TheStep12
Global Value13
Global TheStep13
Global Value14
Global TheStep14
Global Toom
Global NewList mylist.s()
Global TheSpeed
Procedure Initialize()
TheSpeed = 10
TimerState = #False
GotToTheEnd = #False
GotToTheStart = #True
HitCounter =0
TheX = 40
TheY = 150
Value = 0
TheStep=1 ;
Value1 = 380
TheStep1=2
Value2 = 100
TheStep2=1
Value3 = 200
TheStep3= 2
Value4 = 300
TheStep4=2
Value5 = 50
TheStep5=-1
Value6 = 250
TheStep6=3
Value7 = 20
TheStep7=1
Value8 = 340
TheStep8=-3
Value9 = 0
TheStep9=2
Value10 = 230
TheStep10=1
Value11 = 30
TheStep11=-2
Value12 = 180
TheStep12=2
Value13 = 100
TheStep13=-2
Value14 = 300
TheStep14=1
Toom = 1
EndProcedure
Initialize()
Procedure UpdateTimestamp(HitNumber.l)
SetGadgetText(500+HitNumber, StrD((ElapsedMilliseconds()-Start)/1000,2))
EndProcedure
Procedure CollisionProcessor()
CollisionCounter = CollisionCounter + 1
SetGadgetText(#Text_Collisions, "Collisions: " + Str(CollisionCounter))
TimerBallsEnable = #False
RemoveWindowTimer(0,456)
TheSpeed = 0
Delay(1200)
If HitCounter<4
For qoo=501 To 504
SetGadgetText(qoo, "----")
Next
ElseIf HitCounter>4 And HitCounter<8
For qoo=505 To 508
SetGadgetText(qoo, "----")
Next
ElseIf HitCounter>8 And HitCounter<12
For qoo=509 To 512
SetGadgetText(qoo, "----")
Next
ElseIf HitCounter>12 And HitCounter<16
For qoo=513 To 516
SetGadgetText(qoo, "----")
Next
EndIf
OldHitCounter = HitCounter
Initialize()
HitCounter = OldHitCounter
If HitCounter<4
HitCounter = 0
EndIf
If HitCounter>=4 And HitCounter<8
HitCounter = 4
EndIf
If HitCounter>=8 And HitCounter<12
HitCounter = 8
EndIf
If HitCounter>=12
HitCounter = 12
EndIf
TimerBallsEnable = #True
AddWindowTimer(0,456,20)
SetGadgetText(#Text_TimeTrip, "0.00")
EndProcedure
Procedure TimerBalls(Param)
Starti = ElapsedMilliseconds()
TheTimei = 0
Repeat
If TimerBallsEnable = #True
TheTimei = ElapsedMilliseconds()-Starti
If TheTimei>20
Value = Value + TheStep
Value1 = Value1 + TheStep1
Value2 = Value2 + TheStep2
Value3 = Value3 + TheStep3
Value3 = Value3 + TheStep3
Value4 = Value4 + TheStep4
Value5 = Value5 + TheStep5
Value6 = Value6 + TheStep6
Value7 = Value7 + TheStep7
Value8 = Value8 + TheStep8
Value9 = Value9 + TheStep9
Value10 = Value10 + TheStep10
Value11 = Value11 + TheStep11
Value12 = Value12 + TheStep12
Value13 = Value13 + TheStep13
Value14 = Value14 + TheStep14
If Value>=390 Or Value<=0
TheStep = -TheStep
EndIf
If Value1>=390 Or Value1<=0
TheStep1 = -TheStep1
EndIf
If Value2>=390 Or Value2<=0
TheStep2 = -TheStep2
EndIf
If Value3>=390 Or Value3<=0
TheStep3 = -TheStep3
EndIf
If Value4>=390 Or Value4<=0
TheStep4 = -TheStep4
EndIf
If Value5>=390 Or Value5<=0
TheStep5 = -TheStep5
EndIf
If Value6>=390 Or Value6<=0
TheStep6 = -TheStep6
EndIf
If Value7>=390 Or Value7<=0
TheStep7 = -TheStep7
EndIf
If Value8>=390 Or Value8<=0
TheStep8 = -TheStep8
EndIf
If Value9>=390 Or Value9<=0
TheStep9 = -TheStep9
EndIf
If Value10>=390 Or Value10<=0
TheStep10 = -TheStep10
EndIf
If Value11>=390 Or Value11<=0
TheStep11 = -TheStep11
EndIf
If Value12>=390 Or Value12<=0
TheStep12 = -TheStep12
EndIf
If Value13>=390 Or Value13<=0
TheStep13 = -TheStep13
EndIf
If Value14>=390 Or Value14<=0
TheStep14 = -TheStep14
EndIf
Starti = ElapsedMilliseconds()
EndIf
EndIf
ForEver
EndProcedure
If OpenWindow(0, 0, 0, 480, 420, "Dodgy Delivery", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TextGadget(#Text_TimeTrip, 380, 10, 100, 20, "0.00")
TextGadget(#Text_Collisions, 380, 45, 80, 20, "Collisions: 0")
TextGadget(#Text_FirstSetTrips, 380,70,100,20, "1st set of trips")
TextGadget(501, 380, 85, 60, 15, "----")
TextGadget(502, 380, 100, 60, 15, "----")
TextGadget(503, 380, 115, 60, 15, "----")
TextGadget(504, 380, 130, 60, 15, "----")
TextGadget(#Text_SecondSetTrips, 380,150,100,20, "2nd set of trips")
TextGadget(505, 380, 165, 60, 15, "----")
TextGadget(506, 380, 180, 60, 15, "----")
TextGadget(507, 380, 195, 60, 15, "----")
TextGadget(508, 380, 210, 60, 15, "----")
TextGadget(#Text_ThirdSetTrips, 380,230,100,20, "3rd set of trips")
TextGadget(509, 380, 245, 60, 15, "----")
TextGadget(510, 380, 260, 60, 15, "----")
TextGadget(511, 380, 275, 60, 15, "----")
TextGadget(512, 380, 290, 60, 15, "----")
TextGadget(#Text_FourthSetTrips, 380,310,100,20, "4th set of trips")
TextGadget(513, 380, 325, 60, 15, "----")
TextGadget(514, 380, 340, 60, 15, "----")
TextGadget(515, 380, 355, 60, 15, "----")
TextGadget(516, 380, 370, 60, 15, "----")
If LoadFont(1, "Arial", 16)
SetGadgetFont(#Text_TimeTrip, FontID(1))
EndIf
ButtonGadget(#Button_Reset, 380, 390, 60, 20, "Reset")
CanvasGadget(99, 10, 10, 340, 400, #PB_Canvas_Keyboard)
SetActiveGadget(99)
AddWindowTimer(0, 456, 20) ;timer for the trip clock
CreateThread(@TimerBalls(), 999)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget And EventGadget() = 99
If EventType() = #PB_EventType_KeyDown And Toom = 1
key = GetGadgetAttribute(99,#PB_Canvas_Key)
If key = 39
If TimerState = #False
Start = ElapsedMilliseconds()
TimerState = #True
RemoveWindowTimer(0,123)
CountdownTimerAddFlag = #False
CountdownTextPersist = #False
EndIf
TheX = TheX + TheSpeed
ElseIf key = 37
TheX = TheX - TheSpeed
ElseIf key = 38
TheY = TheY - TheSpeed
ElseIf key = 40
TheY = TheY + TheSpeed
EndIf
If TheY<=40
TheY = 40
ElseIf TheY>=340 And HitCounter>=4
TheY = 340
ElseIf TheY>=350 And HitCounter<4
TheY = 350
EndIf
If TheX<=40
TheX = 40
GotToTheStart = #True
If GotToTheEnd = #True
HitCounter = HitCounter+1
UpdateTimestamp(HitCounter)
Start = ElapsedMilliseconds()
GotToTheEnd = #False
If (HitCounter = 4) Or (HitCounter=8) Or (HitCounter = 12)
CountdownTextPersist = #True
TimerState = #False
SetGadgetText(#Text_TimeTrip, "0.00")
EndIf
If HitCounter = 16
RemoveWindowTimer(0,456)
TimerBallsEnable = #False
TheSpeed = 0
GameOverTextPersist = #True
EndIf
EndIf
ElseIf HitCounter>=8
If TheX>=290
TheX = 290
GotToTheEnd = #True
If GotToTheStart = #True
HitCounter = HitCounter+1
UpdateTimestamp(HitCounter)
Start = ElapsedMilliseconds()
GotToTheStart = #False
EndIf
EndIf
ElseIf HitCounter<8
If TheX>=300
TheX = 300
GotToTheEnd = #True
If GotToTheStart = #True
HitCounter = HitCounter+1
UpdateTimestamp(HitCounter)
Start = ElapsedMilliseconds()
GotToTheStart = #False
EndIf
EndIf
EndIf
If Toom = 1
Toom = 0
EndIf
EndIf
EndIf
If Event = #PB_Event_Gadget And EventGadget()= #Button_Reset
RemoveWindowTimer(0,456)
AddWindowTimer(0,456,20)
Initialize()
SetGadgetText(#Text_TimeTrip, "0.00")
For qoo = 501 To 516
SetGadgetText(qoo, "----")
Next
SetGadgetText(#Text_Collisions, "Collisions: 0")
CollisionCounter = 0
RemoveWindowTimer(0,123)
CountdownTimerAddFlag = #False
CountdownTextPersist = #False
TimerBallsEnable = #True
GameOverTextPersist = #False
SetActiveGadget(99)
EndIf
If EventType() = #PB_EventType_KeyUp
Toom = 1
EndIf
If Event = #PB_Event_Timer And EventTimer() = 456 And TimerState = #True
SetGadgetText(#Text_TimeTrip, StrD((ElapsedMilliseconds()-Start)/1000,2))
EndIf
;Countdown timer:
If Event = #PB_Event_Timer And EventTimer() = 123
CountdownTimer = CountdownTimer - 1
If CountdownTimer = 0
RemoveWindowTimer(0,123)
CountdownTimerAddFlag = #False
RemoveWindowTimer(0,456)
AddWindowTimer(0,456,20)
Initialize()
CountdownTextPersist = #False
SetGadgetText(#Text_TimeTrip, "0.00")
For qoo = 501 To 516
SetGadgetText(qoo, "----")
Next
SetGadgetText(#Text_Collisions, "Collisions: 0")
CollisionCounter = 0
EndIf
EndIf
StartDrawing(CanvasOutput(99))
Box(0, 0, 320, 400, $FFFFFF)
Box(TheX, TheY, 10, 10, $ff000f)
If HitCounter>=4 And HitCounter<8
Box(TheX, TheY+10, 10, 10, $ff000f) ;added to make crosser 10x20
EndIf
If HitCounter>=8 And HitCounter<12
Box(TheX, TheY+10, 10, 10, $ff000f)
Box(TheX+10, TheY+10, 10, 10, $ff000f) ;added to make crosser L shape - vertical 10x20 and horizontal 20x10
EndIf
If HitCounter>=12
Box(TheX, TheY+10, 10, 10, $ff000f)
Box(TheX+10, TheY+10, 10, 10, $ff000f)
Box(TheX+10, TheY, 10, 10, $ff000f) ;added to make a square 20x20
EndIf
LineXY(40, 360, 40, 40, $0000FF)
LineXY(310, 360, 310, 40, $0000FF)
LineXY(40, 40, 310, 40, $0000FF)
LineXY(40, 360, 310, 360, $0000FF)
Box(100, Value, 10, 10, 126)
Box(110, Value1, 10, 10, 126)
Box(120, Value2, 10, 10, 126)
Box(130, Value3, 10, 10, 126)
Box(140, Value4, 10, 10, 126)
Box(150, Value5, 10, 10, 126)
Box(160, Value6, 10, 10, 126)
Box(170, Value7, 10, 10, 126)
Box(180, Value8, 10, 10, 126)
Box(190, Value9, 10, 10, 126)
Box(200, Value10, 10, 10, 126)
Box(210, Value11, 10, 10, 126)
Box(220, Value12, 10, 10, 126)
Box(230, Value13, 10, 10, 126)
Box(240, Value14, 10, 10, 126)
If CountdownTextPersist = #True
If CountdownTimerAddFlag = #False
CountdownTimer = 20
AddWindowTimer(0, 123, 1000) ;countdown timer
CountdownTimerAddFlag = #True
EndIf
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(100, 150, "Begin next set of", RGB(255, 0, 0))
DrawText(100, 170, "trips within", RGB(255, 0, 0))
DrawText(174, 170, Str(CountdownTimer), RGB(255, 0, 0))
If CountdownTimer>=10
DrawText(193, 170, "secs", RGB(255, 0, 0))
Else
DrawText(184, 170, "secs", RGB(255, 0, 0))
EndIf
EndIf
If GameOverTextPersist = #True
TimeSum.d=0
For qoo = 501 To 516
TimeSum = TimeSum + ValD(GetGadgetText(qoo))
Next
TotTime.s = StrD(TimeSum,2)
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(120, 150, "GAME OVER!", RGB(255, 0, 0))
DrawText(100, 170, "Total Trip Time:", RGB(255, 0, 0))
DrawText(204, 170, TotTime, RGB(255, 0, 0))
DrawText(120, 190, "Crashes:", RGB(255, 0, 0))
DrawText(182, 190, Str(CollisionCounter), RGB(255, 0, 0))
EndIf
StopDrawing()
ClearList(mylist())
AddElement(mylist()) : mylist() = "100" + ";" + Str(value)
AddElement(mylist()) : mylist() = "110" + ";" + Str(value1)
AddElement(mylist()) : mylist() = "120" + ";" + Str(value2)
AddElement(mylist()) : mylist() = "130" + ";" + Str(value3)
AddElement(mylist()) : mylist() = "140" + ";" + Str(value4)
AddElement(mylist()) : mylist() = "150" + ";" + Str(value5)
AddElement(mylist()) : mylist() = "160" + ";" + Str(value6)
AddElement(mylist()) : mylist() = "170" + ";" + Str(value7)
AddElement(mylist()) : mylist() = "180" + ";" + Str(value8)
AddElement(mylist()) : mylist() = "190" + ";" + Str(value9)
AddElement(mylist()) : mylist() = "200" + ";" + Str(value10)
AddElement(mylist()) : mylist() = "210" + ";" + Str(value11)
AddElement(mylist()) : mylist() = "220" + ";" + Str(value12)
AddElement(mylist()) : mylist() = "230" + ";" + Str(value13)
AddElement(mylist()) : mylist() = "240" + ";" + Str(value14)
ResetList(mylist())
While NextElement(mylist())
Cru = Val(StringField(mylist(),1,";"))
Magoo = Val(StringField(mylist(),2,";"))
If HitCounter<4
If Cru = TheX And (Magoo = TheY Or Magoo = TheY-10 Or Magoo = TheY+10) ;this is if the crosser is 10x10
CollisionProcessor()
EndIf
EndIf
If HitCounter>=4 And HitCounter<8
If Cru = TheX And Magoo>=theY-10 And Magoo<=TheY+20 ;this is if the crosser is 10x20
CollisionProcessor()
EndIf
EndIf
If HitCounter>=8 And HitCounter<12
If (Cru = TheX And Magoo>=TheY-10 And Magoo<=TheY+20) Or (Cru = TheX+10 And Magoo>=TheY And Magoo<=TheY+20) ;this is if the crosser is L shaped - vertical 10x20 and horizontal 20x10
CollisionProcessor()
EndIf
EndIf
If HitCounter>=12
If Cru>=TheX And Cru<=TheX+10 And Magoo>=TheY-10 And Magoo<=TheY+20 ;this is if the crosser is 20x20
CollisionProcessor()
EndIf
EndIf
Wend
Until Event = #PB_Event_CloseWindow
EndIf