- ;******************************************************************************************************
- ;*
- ;* PUREBR3AKER (c)BGAMES 2005
- ;* Lead coder : djes@free.fr
- ;*
- ;* http://www.shootingcrew.com/
- ;*
- ;******************************************************************************************************
- #CREATEPACKS = #False
- XIncludeFile "packlib_release.pbi"
- ;******************************************************************************************************
- ;- *** CONSTANTS ***
- ;******************************************************************************************************
- ;- Sprites
- Enumeration #PB_Compiler_EnumerationValue Step 1
- #DUCK_GUN
- #DUCK_AMMO
- #DUCK_DUCK0
- #DUCK_DUCK1
- #DUCK_DUCK2
- #DUCK_CADDIE
- #DUCK_ESCARGOT
- #DUCK_POULE
- #DUCK_VEAU
- #DUCK_DUCK0F
- #DUCK_DUCK1F
- #DUCK_DUCK2F
- #DUCK_CADDIEF
- #DUCK_ESCARGOTF
- #DUCK_POULEF
- #DUCK_VEAUF
- EndEnumeration
- ;- Sprites Fonts
- Enumeration #PB_Compiler_EnumerationValue Step 256
- #SILVERFONT
- EndEnumeration
- ;- Sounds
- Enumeration
- #M2EXPLOSION
- #EXTRALIFE
- #NEXTLEVELSND
- #CREDITS
- #CLOCK
- #TOC
- EndEnumeration
- ;******************************************************************************************************
- ;- *** STRUCTURES ***
- ;******************************************************************************************************
- Structure duck
- x.f
- y.l
- x_speed.f
- sprite_nb.l
- EndStructure
- Structure duck_ammo
- x.l
- y.l
- EndStructure
- Structure anim
- X.f
- x_speed.f
- Y.f
- y_speed.f
- zoom.f
- zoom_speed.f
- current_sprite_nb.f
- anim_speed.f
- first_sprite.l
- last_sprite.l
- current_fade.f
- fade_speed.f
- current_time.l
- duration.l ;in frames
- pause_in.l ;before anim start
- pause_out.l ;after anim
- EndStructure
- ;******************************************************************************************************
- ;- *** GLOBALS ***
- ;******************************************************************************************************
- Global Dim silverfont.l(255)
- Global NewList anims.anim()
- Global screen_width = 1024
- Global screen_height = 768
- Global screen_depth = 32
- Global refresh_rate = 60
- Global ingame_music = #True
- Global ingame_sound = #True
- ;******************************************************************************************************
- ;- *** PROCEDURES ***
- ;******************************************************************************************************
- Procedure.i realround(nb.f)
- !cvtss2si eax, [p.v_nb]
- ProcedureReturn
- EndProcedure
- ;******************************************************************************************************
- Procedure LoadMidi(Nb, file.s)
- i = mciSendString_("open " + file.s + " type sequencer alias mid" + STR(Nb), 0, 0, 0)
- ProcedureReturn i
- EndProcedure
- Procedure PlayMidi(Nb)
- i = mciSendString_("play mid" + STR(Nb), 0, 0, 0)
- ProcedureReturn i
- EndProcedure
- Procedure StopMidi(Nb)
- i = mciSendString_("stop mid" + STR(Nb), 0, 0, 0)
- ProcedureReturn i
- EndProcedure
- Procedure FreeMidi(Nb)
- i = mciSendString_("close mid" + STR(Nb), 0, 0, 0)
- ProcedureReturn i
- EndProcedure
- Procedure SetMidivolume(Nb, volume)
- i = mciSendString_("set volume" + STR(Nb) + " volume " + STR(volume), 0, 0, 0)
- ProcedureReturn i
- EndProcedure
- ;******************************************************************************************************
- ; Draw an animated screen centered text
- Procedure centered_text(text.s, pause_in.l)
-
- xs = 0 + screen_width / 2 - ((Len(text) - 1) * 40) / 2
- ys = 0 + screen_height / 2 - 19
-
- For u = 1 To Len(text)
-
- AddElement(anims())
- anims()x = xs
- anims()x_speed = 0
- anims()y = ys
- anims()y_speed = 2
- anims()current_sprite_nb = #SILVERFONT + Asc(Mid(text, u, 1))
- anims()anim_speed = 0
- anims()current_time = - pause_in
- anims()duration = 85 ;(255 / 3)
- anims()current_fade = 255
- anims()fade_speed = - 3
- anims()pause_in = 1.5 * refresh_rate
- anims()pause_out = 0
- anims()zoom = 1
- anims()zoom_speed = 0
-
- AddElement(anims())
- anims()x = xs
- anims()x_speed = 0
- anims()y = ys
- anims()y_speed = - 2
- anims()current_sprite_nb = #SILVERFONT + Asc(Mid(text, u, 1))
- anims()anim_speed = 0
- anims()current_time = - pause_in
- anims()duration = 85 ;(255 / 3)
- anims()current_fade = 255
- anims()fade_speed = - 3
- anims()pause_in = 1.5 * refresh_rate
- anims()pause_out = 0
- anims()zoom = 1
- anims()zoom_speed = 0
- xs + 40
-
- Next u
-
- EndProcedure
- Procedure textxy(text.s, x.l, y.l)
-
- For u = 1 To Len(text)
- s.l = #SILVERFONT + Asc(Mid(text, u, 1))
- ZoomSprite3D(s, 64, 64)
- RotateSprite3D(s, 0, 0)
- DisplaySprite3D(s, x, y)
- x + 32
- Next u
-
- EndProcedure
- ;******************************************************************************************************
- ;play specified sound specifying parameters
- Procedure play_sound(sound.l, pan.l = - 1, volume.l = - 1, frequency.l = - 1)
- If ingame_sound
- If pan<> - 1
- SoundPan(sound, pan)
- EndIf
- If volume<> - 1
- SoundVolume(sound, volume)
- EndIf
- If frequency<> - 1
- SoundFrequency(sound, frequency)
- EndIf
- PlaySound(sound, #PB_Sound_MultiChannel)
- EndIf
- EndProcedure
- ;******************************************************************************************************
- Procedure GameLoading()
-
- PackName.s = "packs/ducks.pak"
- PackCounter = 0
-
- Media$ = #NULL$
- PackLoadSprite3D(#DUCK_GUN, Media$ + "gfx/canon.png")
- PackLoadSprite3D(#DUCK_AMMO, Media$ + "gfx/balle.png")
- PackLoadSprite3D(#DUCK_DUCK0, Media$ + "gfx/canard0.png")
- PackLoadSprite3D(#DUCK_DUCK1, Media$ + "gfx/canard1.png")
- PackLoadSprite3D(#DUCK_DUCK2, Media$ + "gfx/canard2.png")
- PackLoadSprite3D(#DUCK_CADDIE, Media$ + "gfx/caddie.png")
- PackLoadSprite3D(#DUCK_ESCARGOT, Media$ + "gfx/escargot.png")
- PackLoadSprite3D(#DUCK_POULE, Media$ + "gfx/poule.png")
- PackLoadSprite3D(#DUCK_VEAU, Media$ + "gfx/veau.png")
- PackLoadSprite3D(#DUCK_DUCK0F, Media$ + "gfx/canard0_f.png")
- PackLoadSprite3D(#DUCK_DUCK1F, Media$ + "gfx/canard1_f.png")
- PackLoadSprite3D(#DUCK_DUCK2F, Media$ + "gfx/canard2_f.png")
- PackLoadSprite3D(#DUCK_CADDIEF, Media$ + "gfx/caddie_f.png")
- PackLoadSprite3D(#DUCK_ESCARGOTF, Media$ + "gfx/escargot_f.png")
- PackLoadSprite3D(#DUCK_POULEF, Media$ + "gfx/poule_f.png")
- PackLoadSprite3D(#DUCK_VEAUF, Media$ + "gfx/veau_f.png")
-
- n.l = 1
- For u = Asc("A") To Asc("Z")
- silverfont(u) = n
- n + 1
- Next u
- silverfont(Asc("!")) = n : n + 1
- silverfont(Asc("'")) = n : n + 1
- silverfont(Asc("(")) = n : n + 1
- silverfont(Asc(")")) = n : n + 1
- silverfont(Asc(" - ")) = n : n + 1
- silverfont(Asc(".")) = n : n + 1
- silverfont(Asc("?")) = n : n + 1
- silverfont(Asc(":")) = n : n + 1
- silverfont(Asc("0")) = n : n + 1
- silverfont(Asc("1")) = n : n + 1
- silverfont(Asc("2")) = n : n + 1
- silverfont(Asc("3")) = n : n + 1
- silverfont(Asc("4")) = n : n + 1
- silverfont(Asc("5")) = n : n + 1
- silverfont(Asc("6")) = n : n + 1
- silverfont(Asc("7")) = n : n + 1
- silverfont(Asc("8")) = n : n + 1
- silverfont(Asc("9")) = n : n + 1
- silverfont(Asc(", ")) = n : n + 1
- silverfont(Asc(" ")) = n : n + 1
-
- For u = 0 To 255
- If silverfont(u)<>0
- PackLoadSprite3D(#SILVERFONT + u, "gfx/fonts/silver/silver-" + StrU(silverfont(u), #PB_Byte) + ".png")
- EndIf
- Next u
-
- ClosePack()
-
- PackName = "packs/sounds.pak"
- PackCounter = 0
-
- PackLoadSound(#M2EXPLOSION, "sfx/m2fire.wav")
- PackLoadSound(#EXTRALIFE, "sfx/HAPPYBEL.WAV")
- PackLoadSound(#NEXTLEVELSND, "sfx/SOUND827.WAV")
- PackLoadSound(#CLOCK, "sfx/inter.WAV")
- PackLoadSound(#TOC, "sfx/bounce1.wav")
- ClosePack()
-
- EndProcedure
- ;******************************************************************************************************
- Procedure FullScreenCheck()
- If ingame_music
- StopMidi(1)
- EndIf
-
- ReleaseMouse(1)
- CloseScreen()
-
- OpenWindow(0, 0, 0, 256, 256, "Dux", #PB_Window_Minimize)
-
- Repeat
- Event = WaitWindowEvent()
- Until Event = #PB_Event_ActivateWindow
-
- CloseWindow(0)
- OpenScreen(screen_width, screen_height, screen_depth, "Ducks")
- ReleaseMouse(0)
-
- GameLoading()
-
- If ingame_music
- playMidi(1)
- EndIf
- EndProcedure
- ;******************************************************************************************************
- ;- INIT
- ;******************************************************************************************************
- UsePNGImageDecoder()
- UseTIFFImageDecoder()
- UseJPEGImageDecoder()
- UseOGGSoundDecoder()
- If (InitSprite() AND InitSprite3D() AND InitKeyboard() AND InitMouse() AND InitSound()) = #False
- End
- EndIf
- screen_width = 1024
- screen_height = 768
- screen_depth = 32
- refresh_rate = 60
- ingame_music = #True
- OpenScreen(screen_width, screen_height, screen_depth, "Dux", #PB_Screen_WaitSynchronization, refresh_rate)
- Sprite3DQuality(1)
- ;******************************************************************************************************
- ;- *** MAIN ***
- ;******************************************************************************************************
- START_DUX:
- Global NewList ducks.duck()
- Global NewList ducks_ammos.duck_ammo()
- Global duck_score = 10
- speedup.f = 0
- GameLoading()
- If ingame_music
- LoadMidi(1, "sfxballgame.mid")
- SetMidivolume(1, 150)
- PlayMidi(1) ; le joue
- EndIf
- ClearList(anims())
- centered_text("DUX !", 2 * refresh_rate)
- ducks_win = #False
- Repeat
-
- If NOT IsScreenActive()
- FullScreenCheck()
- Else
- Gosub INPUTS
- Gosub DUX_LOGIC
- EndIf
-
- Gosub DRAWING
-
- FlipBuffers() ;vbl synchro ON : better
- frame_counter + 1
-
- Until quit = 1
- quit = 0
- If ingame_music
- StopMidi(1)
- FreeMidi(1)
- EndIf
- ClearList(anims())
- End
- ;******************************************************************************************************
- ;- *** SUBROUTINES ***
- ;******************************************************************************************************
- ;-DRAWING
- DRAWING:
- ClearScreen($550000)
- StartDrawing(ScreenOutput())
- LineXY(0, 32 + 32, 1023, 32 + 32, $AAAAAA)
- LineXY(0, 132 + 32, 1023, 132 + 32, $AAAAAA)
- LineXY(0, 232 + 32, 1023, 232 + 32, $AAAAAA)
- StopDrawing()
- If Start3D()
-
- Gosub ANIMATIONS_DISPLAY
-
- ForEach ducks()
- RotateSprite3D(ducks()sprite_nb, 10 * Sin(ducks()x / 8), 0)
- DisplaySprite3D(ducks()sprite_nb, ducks()x - SpriteWidth(#DUCK_DUCK0) / 2, ducks()y - SpriteHeight(#DUCK_DUCK0) / 2)
- Next
- Sprite3DQuality(0)
- ForEach ducks_ammos()
- DisplaySprite3D(#DUCK_AMMO, ducks_ammos()x - SpriteWidth(#DUCK_AMMO) / 2, ducks_ammos()y - SpriteHeight(#DUCK_AMMO) / 2)
- Next
- DisplaySprite3D(#DUCK_GUN, xmouse - SpriteWidth(#DUCK_GUN) / 2, ymouse)
- Sprite3DQuality(1)
-
- If duck_score >= 0
- textxy STR(duck_score), 900 - Len STR(duck_score)) * 32 / 2, 768 - 100)
- EndIf
-
- Stop3D()
-
- EndIf
- Return
- ;******************************************************************************************************
- ;-DUX LOGIC
- DUX_LOGIC:
- ForEach ducks()
- Select ducks()y
- Case 32
- ducks()x = ducks()x + ducks()x_speed + speedup
- If ducks()x >= screen_width + SpriteWidth(#DUCK_DUCK0) / 2
- ducks()y = 132
- ducks()x_speed + 1
- If ducks()sprite_nb = #DUCK_DUCK0F
- ducks()sprite_nb = #DUCK_DUCK1
- Else
- ducks()sprite_nb - 7 ;flip vertically
- EndIf
- EndIf
- Case 132
- ducks()x = ducks()x - ducks()x_speed - speedup
- If ducks()x <= - SpriteWidth(ducks()sprite_nb) / 2
- ducks()y = 232
- ducks()x_speed + 1
- If ducks()sprite_nb = #DUCK_DUCK1
- ducks()sprite_nb = #DUCK_DUCK2F
- Else
- ducks()sprite_nb + 7 ;flip vertically
- EndIf
- EndIf
- Case 232
- ducks()x = ducks()x + ducks()x_speed + speedup
- If ducks()x >= screen_width + SpriteWidth(#DUCK_DUCK0) / 2
- If ducks()sprite_nb = #DUCK_DUCK2F
- duck_score - 5
- play_sound(#CLOCK, - 1, - 1, 500 )
- ;Beep_(500, 1)
- EndIf
- DeleteElement(ducks(), 1)
- EndIf
- EndSelect
- Next
- ;new duck
- If frame_counter%refresh_rate = 0
- AddElement(ducks())
- ducks()x = - SpriteWidth(#DUCK_DUCK0F)
- ducks()y = 32
- ducks()x_speed = 1
- If Random(10)<5
- ducks()sprite_nb = #DUCK_DUCK0F
- Else
- ducks()sprite_nb = #DUCK_CADDIEF + Random(3)
- EndIf
- EndIf
- ;every 30 secs, speedup
- If frame_counter%(refresh_rate * 30) = 0
- speedup + 0.1
- EndIf
- If duck_score > 0
- ;draw ammos, and compute collisions
- ForEach ducks_ammos()
- ducks_ammos()y - 10
- If ducks_ammos()y <= - 10
- DeleteElement(ducks_ammos())
- Else
- ForEach ducks()
- If ducks_ammos()x >= ducks()x - 16 AND ducks_ammos()x <= ducks()x + 16 AND ducks_ammos()y >= ducks()y - 16 AND ducks_ammos()y <= ducks()y + 16
- Select ducks()sprite_nb
- Case #DUCK_DUCK0, #DUCK_DUCK0F
- duck_score + 1
- ;Beep_(5000, 10)
- play_sound(#TOC, - 1, - 1, 5000 )
- Case #DUCK_DUCK1, #DUCK_DUCK1F
- duck_score + 2
- ;Beep_(5000, 10)
- play_sound(#TOC, - 1, - 1, 5000 )
- Case #DUCK_DUCK2, #DUCK_DUCK2F
- duck_score + 3
- ;Beep_(5000, 10)
- play_sound(#TOC, - 1, - 1, 5000 )
- Case #DUCK_CADDIE, #DUCK_CADDIEF
- duck_score - 4
- ;Beep_(50, 30)
- play_sound(#TOC, - 1, - 1, 50 )
- Case #DUCK_POULE, #DUCK_POULEF
- duck_score - 2
- ;Beep_(60, 30)
- play_sound(#TOC, - 1, - 1, 60 )
- Case #DUCK_VEAU, #DUCK_VEAUF
- duck_score - 3
- ;Beep_(80, 30)
- play_sound(#TOC, - 1, - 1, 80 )
- Case #DUCK_ESCARGOT, #DUCK_ESCARGOTF
- duck_score - 1
- ;Beep_(100, 30)
- play_sound(#TOC, - 1, - 1, 100 )
-
- EndSelect
- DeleteElement(ducks(), 1)
- DeleteElement(ducks_ammos(), 1)
- Break 2
- EndIf
- Next
- EndIf
- Next
-
- If duck_score <= 0
- centered_text("GAME OVER !", 2 * refresh_rate)
- ClearList(ducks_ammos())
- EndIf
-
- EndIf
- If duck_score = 50 AND ducks_win = #False
- play_sound(#EXTRALIFE, 0, 100, 20000)
- centered_text("WELL DONE !", 2 * refresh_rate)
- ducks_win = #True
- EndIf
- Return
- ;******************************************************************************************************
- ;-INPUTS
- INPUTS:
- ExamineKeyboard()
- ExamineMouse()
- If joystick_switch
- joyGetPosEx_(#JOYSTICKID1, joyInfoEx.JOYINFOEX)
- EndIf
- If KeyboardReleased(#PB_Key_J)
- joystick_switch = ~joystick_switch
- EndIf
- If KeyboardReleased(#PB_Key_Escape)
- quit = 1
- EndIf
- If KeyboardReleased(#PB_Key_S)
- u = GrabSprite(#PB_Any, 0, 0, 1024, 768)
- SaveSprite(u, "c:screenshot.bmp")
- EndIf
- ;gun, and fire
- If KeyboardPushed(#PB_Key_Left)
- key_x_speed - 1
- ElseIf KeyboardPushed(#PB_Key_Right)
- key_x_speed + 1
- Else
- key_x_speed / 2
- EndIf
- ;Joystick or mouse control
- If joystick_switch
- If JoyXamp<>0
- u = realround((joyInfoExdwXpos - (JoyXamp / 2)) / 2048) ;this little operation to optimise precision
- xmouse + ((u * 2048) * 64) / JoyXamp
- EndIf
- Else
- xmouse = xmouse + MouseDeltaX() + key_x_speed
- ;xmouse.l = MouseX()
- EndIf
- If xmouse<0 : xmouse = 0 : EndIf
- If xmouse>1023 : xmouse = 1023 : EndIf
- ymouse = 768 - SpriteHeight(#DUCK_GUN)
- If mb = #True AND (MouseButton(1) = 0 OR ((joyInfoExdwButtons&1 = 0) AND joystick_switch))
- ;évite la répétition
- mb = #False
- EndIf
- If duck_fire_delay>0
- duck_fire_delay - 1
- EndIf
- If (MouseButton(1) OR KeyboardPushed(#PB_Key_Return) OR ((joyInfoExdwButtons&1) AND joystick_switch)) AND mb = #False AND duck_fire_delay = 0 AND duck_score > 0
- AddElement(ducks_ammos())
- play_sound(#M2EXPLOSION)
- ;Beep_(1000, 2)
- ducks_ammos()x = xmouse
- ducks_ammos()y = ymouse + 10
- mb = #True
- duck_fire_delay = refresh_rate / 8
- EndIf
- Return
- ;******************************************************************************************************
- ;- ANIMATIONS_DISPLAY
- ; Multi purposes (why not for explosions? maybe later ;)
- ANIMATIONS_DISPLAY:
- Sprite3DQuality(1)
- With anims()
- ; If FirstElement(anims())<>0
- ; ResetList(anims())
- ForEach anims()
- If current_time
-
- ;hint to start displaying after a while : make current_time negative
- If current_time<0
-
- current_time + 1
-
- Else
-
- u = current_sprite_nb
- sw.f = zoom * SpriteWidth(u)
- sh.f = zoom * SpriteHeight(u)
- ZoomSprite3D(u, sw, sh)
- DisplaySprite3D(u, x - sw / 2, y - sh / 2, current_fade)
- ;DisplaySprite3D(u, x - SpriteWidth(u) / 2, y - SpriteHeight(u) / 2, current_fade)
-
- ;pause before anim?
- If pause_in = 0
-
- ;anim
- current_sprite_nb + anim_speed
- If last_sprite<>first_sprite
- ;if sprite is animated, and for a certain amount of frames, test boundaries
- If current_sprite_nb>last_sprite
- current_sprite_nb = first_sprite
- EndIf
- EndIf
- current_fade + fade_speed
- current_time + 1
- x + x_speed
- y + y_speed
- zoom + zoom_speed
- Else
- pause_in - 1
- EndIf
-
- EndIf
-
- Else
- If pause_out<>0
- ;pause after anim?
- u = current_sprite_nb
- sw.f = zoom * SpriteWidth(u)
- sh.f = zoom * SpriteHeight(u)
- ZoomSprite3D(u, sw, sh)
- DisplaySprite3D(u, x - sw / 2, y - sh / 2, current_fade)
- ;DisplaySprite3D(u, x - SpriteWidth(u) / 2, y - SpriteHeight(u) / 2, current_fade)
- pause_out - 1
- Else
- ;no, delete
- DeleteElement(anims())
- EndIf
- EndIf
- ; EndIf
- Next
- EndWith
- Return