Code: Select all
this is my first post on this forum. Some of you already know me; for all the others, here's my short story:
- I've been an Amigan since the nineties (A2000HD which, unfortunately, I used very little);
- re-joined the Community a couple of years ago (now running Sam440ep-flex @800, AmigaOS4.1.2 ... soon upgrading);
- now member of just-reborn ATO (Amiga Translators' Organization) Italy;
- currently learning how to code in Hollywood.
I've written a small 2D game featuring Sub-Zero (MKIII versions) against the Bouncing Ball. The code is for non commercial use only, so i believe all graphics is used (and shall be used) in a "Fair way" (check also this web link for more infos http://www.bghq.com/copyright_info.php ).
Nonetheless, I'd like to have administrator clearance before posting graphics and music.
For the moment, here is the code.
Please note that the code is working but still needs adjusting, since it crashes a lot due to sprite conflict.
Gianluca aka g0blin
Code: Select all
/****************************************************************
** **
** Name: Sub-Zero vs Amiga **
** Author: Gianluca Girelli **
** Version: 1.3 **
** Date: 31.08.2011 **
** Interpreter: Hollywood 4.5 **
** Licence: Hollywood initial coding demo **
** Function: This is my first real try on Hollywood coding. **
** The purpose is learning the basics and deal **
** with sprites. **
** **
** History: **
** **
** 1.3 (31.08.11) **
** - now implementing intro, main menu and credits routine. **
** **
** 1.2 (20.07.11) **
** - now implementing basic end-game routine when either **
** life counter reaches 0. Animations have been fixed using **
** custom frame grabber routine. At this stage, anyway, game **
** is still a proof of concept. **
** **
** 1.1 (05.07.11) **
** - uses nested If-ElseIf statements to avoid sprite problems **
** - Collision() command inserted to detect combat in progress **
** - introduces sprites flipping if fighters get back-to-back **
** **
** 1.0: (22.06.11) **
** - initial release **
** **
****************************************************************/
@APPTITLE "Sub-Zero vs Amiga"
@APPAUTHOR "Gianluca Girelli"
@APPCOPYRIGHT "Freeware - Graphics copyrights remain of original authors."
@APPVERSION "$VER: 1.3 (31.08.2011)"
@APPDESCRIPTION "Simple fighting game featuring Sub-Zero from MKIII."
@VERSION 4,5
@INCLUDE "company-intro.hws"
@DISPLAY 1, { Title = "'Sub-Zero vs Amiga' - Made on Amiga with Hollywood by g0blin",
X=#CENTER, Y=#CENTER, Width=790, Height=506, HidePointer=True,
Sizeable=True, ScaleMode=#SCALEMODE_AUTO }
@SCREEN {Mode = "Ask", Width = 790, Height = 506}
@BRUSH 1, "fighting-stance.png", {Transparency=$0000ff} ; 648x129
@BRUSH 2, "forward.png", {LoadAlpha = True} ; 576X133
@BRUSH 3, "punch.png", {LoadAlpha = True} ; 864X137
@BRUSH 4, "dizzy.png", {Transparency =$ffffff} ; 480X128
@BRUSH 5, "kick.png", {LoadAlpha=True} ; 696x132
@BRUSH 6, "fight.png", {Transparency = $8a030e}
@BRUSH 7, "opponent.png", {Transparency = #BLACK} ; 380X38
@BRUSH 8, "cemetery.png" ; 1185X253
@BRUSH 9, "victory.png", {LoadAlpha = True} ; 40X169
@BRUSH 10, "game_lost.png", {LoadAlpha = True} ; 129x29
@BRUSH 11, "red_boing_ball.png", {Transparency = #BLACK}
@BRUSH 12, "finish-him.png", {Transparency = $770602}
@BRUSH 20, "title.jpg"
@BRUSH 21, "intro2.png"
@BRUSH 22, "versus.png", {LoadAlpha=True}
@BRUSH 30, "lifebar1.png", {Transparency = #BLACK} ; green lifebar
@BRUSH 31, "lifebar2.png", {Transparency = #BLACK} ; red lifebar
@BRUSH 40, "font.png", {Transparency=$0000c0} ; 242x287
@BRUSH 41, "credits.jpg"
@BRUSH 42, "menu_entry1.png", {Transparency = #BLACK}
@BRUSH 43, "menu_entry2.png", {Transparency = #BLACK}
@BRUSH 44, "menu_entry3.png", {Transparency = #BLACK}
@BRUSH 45, "menu_entry4.png", {Transparency = #BLACK}
@BRUSH 46, "arena_thepit.jpg"
CopyBrush(30, 32)
CopyBrush(31, 33)
FlipBrush(32, True)
FlipBrush(33, True)
CreateSprite(1, #BRUSH, 1, 72, 129, 9, 9) ; Sub-Zero fighting stance
CreateSprite(2, #BRUSH, 2, 64, 130, 9, 9) ; Sub-Zero walking
CreateSprite(3, #BRUSH, 3, 96, 137, 9, 9) ; Sub-Zero punching
CreateSprite(4, #BRUSH, 4, 60, 128, 8, 8) ; Sub-Zero dizzy
CreateSprite(5, #BRUSH, 5, 116, 132, 6, 6) ; Sub-Zero kick
CreateSprite(6, #BRUSH, 6, 166, 41, 1, 1) ; fight sign
CreateSprite(7, #BRUSH, 7, 38, 38, 10, 10) ; opponent
CreateSprite(9, #BRUSH, 9, 40, 169, 1, 1) ; Sub-Zero victory pose
CreateSprite(10, #BRUSH, 10, 129, 29, 1, 1) ; Sub-Zero defeated pose
CreateSprite(11, #BRUSH, 11, 64, 70, 7, 7) ; menu pointer/final opponent
CreateSprite(12, #BRUSH, 12, 244, 34, 1, 1) ; fight sign
ScaleSprite(1, 144, 258)
ScaleSprite(2, 128, 260)
ScaleSprite(3, 192, 274)
ScaleSprite(4, 120, 256)
ScaleSprite(5, 232, 266)
ScaleSprite(7, 76, 76)
ScaleSprite(9, 80, 338)
ScaleSprite(10, 258, 58)
ScaleBrush(8, 2370, 506)
ScaleBrush(46, 1100, #KEEPASPRAT)
@SAMPLE 1, "bounce.wav" ; bounce sound
@SAMPLE 2, "Attack1.wav" ; Sub-Zero punching
@SAMPLE 3, "Attack6.wav" ; Sub-Zero kicking
@SAMPLE 4,"Hurt2.wav"
@MUSIC 1, "ending_theme.mp3"
@MUSIC 2, "reptile.mp3"
@MUSIC 3, "Run Rabbit Junk.mp3"
Const #LEVELS=2
Const #MAXLEVELS=3
level=1
Function p_InitGameVars()
EscapeQuit(False) ; disable ESC key as program terminator
f = 1
fr =1
fk =1
sub_x = 0 ; current Sub-Zero x position
sub_y = 506-270 ; current Sub-Zero y position
X = 600 ; current opponent x position
Y = 506-90 ; current opponent y position
sprite_on_screen=1
idle=True ; Sub-Zero is in fighting stance
walking=False ; he's neither walking ....
punching=False ; ... nor punching ....
kicking= False ; ... nor kicking ...
VX = 3.5 ; x velocity (constant 3.5/-3.5)
VY = 3 ; y velocity (dynamic)
Flip = False
player_counter = 340 ; life counters
boing_counter = 340
scrollx = 250
a = 0 ; Switch-Case fighting stance
menutext$={"PLAY", "CREDITS", "CONTROLS", "QUIT"}
creditstext$={"SUB ZERO VS BOING BALL", " ",
"WRITTEN IN HOLLYWOOD", " ",
"ORIGINAL CODE", "GIANLUCA GIRELLI", " ",
"USING CODE BY", "ANDREAS FALKENHAHN", " ",
"GRAPHICS FROM MK III", " ",
"SOUND FX FROM TEKKEN", " ",
"MUSIC FROM MK OST", " ",
"ADDITIONAL MUSIC FROM", "GHOST IN THE SHELL SAC",
" ", " ", "FOR NON COMMERCIAL USE ONLY"}
menuy={100, 200, 300, 400}
selection=-1 ; menu selector
text_pointer=21 ; points to first "text sprite" in list
EndFunction
Function p_GameIntro()
PlayMusic(1)
DisplayBrush(20, #CENTER, #CENTER)
Wait(150)
EndFunction
Function p_Timers()
For Local i=1 To 4 Do StartTimer(i)
EndFunction
Function p_TextToSprite(text$, sprite_number)
; convert a text string in a sprite to be used in menu or credits routine
Local x_pos=y_pos=drawpos=0
CreateBrush(50, 700, 24)
SelectBrush(50)
For pos=0 To StrLen(text$)-1
Local char=Asc(MidStr(text$, pos, 1))
If char>64 And char<75
x_pos=(char-65)*24
y_pos=0
ElseIf char>74 And char<85
x_pos=(char-75)*24
y_pos=23
ElseIf char=32
x_pos=0
y_pos=250
Else
x_pos=(char-85)*24
y_pos=46
EndIf
DisplayBrushPart(40, x_pos, y_pos, drawpos, 0, 24, 23)
drawpos=drawpos+24
Next
EndSelect()
CropBrush(50, 0, 0, drawpos, 24)
SetBrushTransparency(50, #BLACK)
drawpos=0
If sprite_number=25 Or sprite_number=30 Or sprite_number=33
ReplaceColors(50, {$F8F8F8, #RED, $808080, #YELLOW})
Else
ReplaceColors(50, {$F8F8F8, #YELLOW})
EndIf
CreateSprite(sprite_number, #BRUSH, 50)
FreeBrush(50)
EndFunction
Function p_SetUpTextGfx()
For i=21 To 24 Do p_TextToSprite(menutext$[i-21], i)
For i=25 To 45 Do p_TextToSprite(creditstext$[i-25], i)
EndFunction
Function p_DisplayGameGfx()
; displays and updates in-game graphics
If player_counter<=20 Then player_counter=20
If boing_counter<=20 Then boing_counter=20
DisplayBrushPart(8,scrollx,0,0,0,790,506) ; scrolling background
DisplayBrush(31, #LEFT, #TOP)
DisplayBrush(33, #RIGHT, #TOP)
DisplayBrushPart(30, 0, 0, #LEFT, #TOP, player_counter, 41)
DisplayBrushPart(32, 0, 0, #RIGHT, #TOP, boing_counter, 41)
EndFunction
Function p_DisplayControls()
; simple screen which shows in-game controls
Cls
Repeat
If GetTimer(4) > 75
If f > 8
f =1
Else
f = f + 1
EndIf
DisplaySprite(1, 0, #CENTER, f)
StartTimer(4)
EndIf
For Local k=42 To 45
DisplayBrush(k, 200, menuy[k-42])
Next
WaitTimer(1, 40)
Until IsKeyDown("ESC")
RemoveSprite(1)
DisplaySprite(9, 25, #CENTER)
Wait(100)
p_PrepareMenu()
EndFunction
Function p_Credits()
; play end-game rolling credits and music
PlayMusic(3)
Local scroll_y=506
Local x = {}
Local speed=1
For Local i=25 To 45
x[i]=GetAttribute(#SPRITE, i, #ATTRWIDTH)
Next
RemoveSprites()
Cls
DisplayBrush(41, #CENTER, #CENTER)
Repeat
For Local i=25 To 45 Do DisplaySprite(i, (GetAttribute(#DISPLAY, 0, #ATTRWIDTH)-x[i])\2, scroll_y+50*(i-25))
scroll_y=scroll_y-speed
If scroll_y<(-1000) Then scroll_y=550
WaitTimer(1, 40)
Until IsKeyDown("ESC")
p_PrepareMenu()
StopMusic(3)
EndFunction
Function p_SetUpGameGfx()
; sets up in-game graphics
DisplayBrushPart(8,scrollx,0,0,0,790,506) ; scrolling background
DisplayBrush(31, #LEFT, #TOP) ; display fully depleted life bars ..
DisplayBrush(33, #RIGHT, #TOP)
DisplayBrush(30, #LEFT, #TOP) ; .. and overlay them with green bars
DisplayBrush(32, #RIGHT, #TOP)
EndFunction
Function p_MoveAndAnimateOpponent()
X = X + VX
Y = Y + VY
; bounce up now!
If Y >= 420
VY = -Rnd(3) - 5
bounceup = True
;PlaySample(1)
EndIf
; and fall down!
If VY >= 0 And bounceup = True
VY = Rnd(4)
bounceup = False
EndIf
; bounce against right border!
If X >= 714
VX = -3.5
;PlaySample(1) ;, {pitch=16000})
EndIf
; bounce against left border!
If X < 2
VX = 3.5
;PlaySample(1);, {pitch=16000})
EndIf
; dynamic velocity
VY = VY + 0.1
DisplaySprite(7, X, Y)
EndFunction
Function p_GameOver()
RemoveSprites()
DisplaySprite(10, #CENTER, 430)
Wait(200)
gameover=True
EndFunction
/*Function p_GameOver(); old routine
RemoveSprites()
If boing_counter<=0
DisplaySprite(9, 380, 150)
ElseIf player_counter<=0
DisplaySprite(10, #CENTER, 430)
EndIf
Wait(200)
End
EndFunction */
Function p_NextLevel()
;transition to next level:
; - change opponent
; - if #MAXLEVELS then p_Credits()
RemoveSprites()
level=level+1
DisplaySprite(9, 380, 150)
Wait(200)
If level=#MAXLEVELS
p_Credits()
Else
FreeBrush(32)
CopyBrush(30,32)
FlipBrush(32, True)
p_InitGame()
EndIf
EndFunction
Function p_ReadPlayerInput()
If IsKeyDown("LEFT") And scrollx > 0
scrollx = scrollx - 2
If sub_x > 0 Then sub_x = sub_x - 2
a = 1
ElseIf IsKeyDown("RIGHT") And scrollx < 1400
scrollx = scrollx + 2
If sub_x < 790-128 Then sub_x = sub_x + 2
a = 2
ElseIf IsKeyDown("a") Or IsKeyDown("A")
a = 3
ElseIf IsKeyDown("x") Or IsKeyDown("X")
a=4
EndIf
EndFunction
Function p_FlipFighters(sprite)
If (X<sub_x) And flip=False ;flip sprites if ball is behind fighter
RemoveSprite(sprite)
FlipSprite(sprite, True)
flip=True
EndIf
If (X>sub_x) And flip=True ;flip sprites back
RemoveSprite(sprite)
FlipSprite(sprite, True)
flip=False
EndIf
EndFunction
Function p_MoveAndAnimatePlayer()
Switch a
Case 1: ; Sub-Zero walking backward
If idle
RemoveSprite(1)
idle = False
walking=True
EndIf
If punching
RemoveSprite(3)
punching = False
walking=True
EndIf
; switch frames every 80ms
If GetTimer(2) > 80
If fr < 1
fr = 9
Else
fr = fr - 1
EndIf
DisplaySprite(2, sub_x, sub_y, fr)
StartTimer(2)
EndIf
sprite_on_screen=2
Case 2: ; Sub-Zero walking forward
walking=True
sprite_on_screen=2
If idle
RemoveSprite(1)
idle = False
EndIf
If punching
RemoveSprite(3)
punching = False
EndIf
If kicking
RemoveSprite(5)
kicking = False
EndIf
; switch frames every 80ms
If GetTimer(2) > 80
If fr > 8
fr =1
Else
fr = fr + 1
EndIf
DisplaySprite(sprite_on_screen, sub_x, sub_y, fr)
StartTimer(2)
EndIf
If Collision(#SPRITE, 7, sprite_on_screen)=True
If IsSamplePlaying(4)=False Then PlaySample(4)
sub_x=sub_x - 30
VX=(-VX)*1.2
player_counter=player_counter-50
If player_counter<=20 Then player_counter=19
EndIf
Case 3: ; Sub-Zero punching
punching = True
If IsSamplePlaying(2)=False Then PlaySample(2)
If idle
RemoveSprite(1)
idle = False
EndIf
If walking
RemoveSprite(2)
walking = False
EndIf
; switch frames every 38ms
If GetTimer(2) > 38
If fr > 8
fr =1
Else
fr = fr + 1
EndIf
DisplaySprite(3, sub_x, sub_y-10, fr)
StartTimer(2)
EndIf
If Collision(#SPRITE, 7, 3) = True
VX=(-VX)*2
boing_counter=boing_counter-20
If boing_counter<=20 Then boing_counter=20
CropBrush(32, 20, 0, boing_counter, 41)
EndIf
Case 4: ; Sub-Zero kicking
kicking = True
If IsSamplePlaying(3)=False Then PlaySample(3)
If idle
RemoveSprite(1)
idle = False
EndIf
If walking
RemoveSprite(2)
walking = False
EndIf
If punching
RemoveSprite(3)
punching = False
EndIf
; switch frames every 45ms
If GetTimer(3) > 45
If fk > 5
fk =1
Else
fk = fk + 1
EndIf
DisplaySprite(5, sub_x, sub_y-10, fk)
StartTimer(3)
EndIf
If Collision(#SPRITE, 7, 5) = True
VX=(-VX)*2
boing_counter=boing_counter-20
If boing_counter<=20 Then boing_counter=19
;CropBrush(32, 20, 0, boing_counter, 41)
EndIf
Default
; switch frames every 110ms
If GetTimer(4) > 75
If f > 8
f =1
Else
f = f + 1
EndIf
If idle = False Then idle = True
If punching
RemoveSprite(3)
punching = False
EndIf
If walking
RemoveSprite(2)
walking = False
EndIf
If kicking
RemoveSprite(5)
kicking = False
EndIf
If player_counter<=20
If f=9 Then f=1 ; because of frame number difference between dizzy and fighting stance
DisplaySprite(4, sub_x, sub_y,f) ; Sub-Zero dizzy
DisplaySprite(12, #CENTER, 200)
If Collision(#SPRITE, 7, 4) = True Then p_GameOver()
Else
DisplaySprite(1, sub_x, sub_y,f) ; Sub-Zero fighting stance
EndIf
If boing_counter<=20 Then p_NextLevel() ;
StartTimer(4)
EndIf
EndSwitch
a=0
EndFunction
Function p_CleanUp() ;not really needed, but a good programming habit
For Local i=1 To 11
If i=6 Then Continue ; check if we really have a sprite or a brush
FreeSprite(i)
FreeBrush(i)
Next
menutext$=Nil ; a little help to the garbage collector
creditstext$=Nil
menuy=Nil
EndFunction
Function p_InitGame()
Cls
p_InitGameVars()
p_SetUpGameGfx()
DisplaySprite(7, X, Y)
DisplaySprite(1, sub_x, sub_y, f)
DisplaySprite(6, #CENTER, #CENTER)
Wait(100)
RemoveSprite(6)
EndFunction
Function p_Game()
; game main loop
PlayMusic(2)
waskeydown=False
gameover=False
p_InitGame()
Repeat
If IsKeyDown("ESC")
gameover=True
waskeydown=True
EndIf
p_ReadPlayerInput()
p_DisplayGameGfx()
p_MoveAndAnimatePlayer()
p_MoveAndAnimateOpponent()
p_FlipFighters(sprite_on_screen)
WaitTimer(1, 40)
Until gameover Or IsKeyDown("ESC")
StopMusic(2)
p_PrepareMenu()
EndFunction
Function p_PrepareMenu()
Cls
DisplayBrush(22, 50, #CENTER)
For Local k=21 To 24
DisplaySprite(k, 350, menuy[k-21])
Next
EndFunction
Function p_MainMenu()
Local y=0
Local scroll=0
Local pan_right=True
p_PrepareMenu()
If IsMusicPlaying(1)=False Then StartMusic(1)
Repeat
If waskeydown=True
Wait(10)
waskeydown=False
EndIf
If IsKeyDown("DOWN")
y=y+1
If y>3 Then y=0
waskeydown=True
ElseIf IsKeyDown("UP")
y=y-1
If y<0 Then y=3
waskeydown=True
EndIf
; switch frames every 50ms
If GetTimer(2) > 50
If fr > 6
fr =1
Else
fr = fr + 1
EndIf
DisplaySprite(11, 550, menuy[y]-30, fr)
DisplayBrushPart(46, scroll ,0,0,0,790,506) ; scrolling background
DisplayBrush(22, 50, #BOTTOM)
If pan_right Then scroll=scroll+1 Else scroll=scroll-1
If scroll>370 Then pan_right=False
If scroll<5 Then pan_right=True
StartTimer(2)
EndIf
If IsKeyDown("RETURN")
Switch y
Case 0:
p_Game() ;play
Case 1:
P_Credits() ;credits
Case 2:
p_DisplayControls() ;display controls
Case 3:
;p_CleanUp()
End
EndSwitch
EndIf
WaitTimer(1, 1000/50)
Forever
If IsMusicPlaying(1) Then StopMusic(1)
EndFunction
/* Begin program */
p_CompanyIntro()
p_GameIntro()
p_Timers()
p_InitGameVars()
p_SetUpTextGfx()
p_MainMenu()
/* End program */