i'm making use of the pc-speaker (beep), so if you have one and your boss is around then better set the constant '#no_sound' to 1.
for keys see the comments in the beginning of the code.
Code: Select all
; >>>>>>> ascii hero <<<<<<<<
;
; keys:
; q : quit
; cntrl : shoot
; left/right : move
; up : jump
; items:
; gun : , (comma)
; laser rifle : _ (underscore)
EnableExplicit
#no_sound = 0
#jump_init = 0.9
#jump_fall = 0.09
Structure s_hero
x.f
y.f
look.l
isjumping.l
jump.f
weapon.l
energy.f
x_prev.l
y_prev.l
sprite.s
EndStructure
Structure s_shot
x.f
y.f
dx.f
dy.f
c.c
byhero.l
x_prev.l
y_prev.l
EndStructure
Structure s_enemy
x.f
y.f
dx.f
dy.f
c.c
firewait.l
energy.f
x_prev.l
y_prev.l
EndStructure
Global hero.s_hero
Global gun_x_prev
Global gun_y_prev
Global NewList enemy.s_enemy()
Global NewList shot.s_shot()
Global xmax,ymax
Global Dim levelmap.c(0,0)
Global redraw=#True
Global redraw_timer
Global quit
Declare shoot(x.f, y.f, dx.f, dy.f, c.c, byhero)
Macro r(f)
Int(Round(f,#PB_Round_Nearest))
EndMacro
Procedure drawSprite(*dat, x, y)
Protected c.c
ConsoleLocate(x,y)
Repeat
c = PeekC(*dat)
Select c
Case #LF :: Break
Case 0 :: y+1 : ConsoleLocate(x,y)
;Case 32 :: x+1 : ConsoleLocate(x,y)
Default :: Print(Chr(c))
EndSelect
*dat + SizeOf(Character)
ForEver
EndProcedure
Procedure loadlevel(*dat)
Protected c.c
Protected x
xmax = Len(PeekS(*dat))-1
;Debug xmax
;CallDebugger
ymax = 0
Dim levelmap(xmax,ymax)
Repeat
c.c = PeekC(*dat)
Select c
Case #LF
Break
Case 0
x=-1
ymax+1
ReDim levelmap(xmax,ymax)
Case '='
AddElement(enemy())
enemy()\x = x
enemy()\y = ymax
enemy()\dx = 0.2 - 0.2*2*Random(1)
enemy()\dy = 0.2 - 0.2*2*Random(1)
enemy()\c = c
enemy()\energy = 2
levelmap(x,ymax) = 32
Default
levelmap(x,ymax) = c
EndSelect
*dat + SizeOf(Character)
x + 1
ForEver
EndProcedure
Procedure drawlevel()
Protected x,y
For x=0 To xmax
For y=1 To ymax
ConsoleLocate(x,y)
Print(Chr(levelmap(x,y)))
Next
Next
EndProcedure
Procedure drawtxt(x,y,txt.s)
Protected lines,n
lines = CountString(txt,#LF$)+1
For n=1 To lines
ConsoleLocate(x,y)
Print(StringField(txt,n,#LF$))
y+1
Next
EndProcedure
Procedure drawlevelxy(x,y)
If x>=0 And x<= xmax And y>=0 And y<=ymax
drawtxt(x,y,Chr(levelmap(x,y)))
EndIf
EndProcedure
Procedure issolid(x,y)
If x>=0 And x<=xmax And y>=0 And y<=ymax
If Chr(levelmap(x,y)) = "#"
ProcedureReturn #True
EndIf
EndIf
ProcedureReturn #False
EndProcedure
Procedure jump()
Protected y_prev
If hero\isjumping
If hero\jump > -0.5
hero\jump - #jump_fall
EndIf
If hero\jump>0 And issolid(hero\x, hero\y-hero\jump)
hero\jump = 0
ElseIf hero\jump<0 And issolid(hero\x, hero\y+1-hero\jump)
hero\isjumping = #False
Else
y_prev = hero\y
hero\y - hero\jump
If r(hero\y) <> y_prev
redraw=#True
EndIf
EndIf
EndIf
EndProcedure
Procedure bullets()
Protected x,y,cont
ForEach shot()
; impacts
If Not shot()\byhero And r(shot()\x) = r(hero\x) And (r(shot()\y) = r(hero\y) Or r(shot()\y) = r(hero\y)+1)
Select shot()\c
Case '.'
hero\energy - 1
drawlevelxy(shot()\x_prev,shot()\y_prev)
drawlevelxy(shot()\x,shot()\y)
DeleteElement(shot())
Continue
EndSelect
EndIf
cont=#False
ForEach enemy()
If shot()\byhero And r(shot()\x) = r(enemy()\x) And r(shot()\y) = r(enemy()\y)
Select shot()\c
Case '.'
enemy()\energy - 0.7
drawlevelxy(shot()\x_prev,shot()\y_prev)
drawlevelxy(shot()\x,shot()\y)
DeleteElement(shot())
cont=#True
Break
Case '_'
enemy()\energy - 2
drawlevelxy(shot()\x_prev,shot()\y_prev)
drawlevelxy(shot()\x,shot()\y)
DeleteElement(shot())
cont=#True
Break
EndSelect
EndIf
Next
If cont
Continue
EndIf
; move
x = shot()\x
y = shot()\y
shot()\x + shot()\dx
shot()\y + shot()\dy
If issolid(shot()\x, shot()\y)
drawlevelxy(shot()\x_prev,shot()\y_prev)
drawlevelxy(shot()\x,shot()\y)
DeleteElement(shot())
redraw=#True
ElseIf shot()\x<0 Or shot()\y<0 Or shot()\x>xmax Or shot()\y>ymax
drawlevelxy(shot()\x_prev,shot()\y_prev)
drawlevelxy(shot()\x,shot()\y)
DeleteElement(shot())
redraw=#True
ElseIf Not redraw
If r(shot()\x) <> x Or r(shot()\y) <> y
redraw=#True
EndIf
EndIf
;redraw=#True
Next
EndProcedure
Procedure lineofsight(x,x2,y)
If x>x2
Swap x,x2
EndIf
For x=x To x2
If issolid(x,y)
ProcedureReturn #False
EndIf
Next
ProcedureReturn #True
EndProcedure
Procedure enemies()
Protected x,y,sight
ForEach enemy()
; die
If enemy()\energy<=0
drawlevelxy(enemy()\x_prev,enemy()\y_prev)
drawlevelxy(enemy()\x,enemy()\y)
DeleteElement(enemy())
Continue
EndIf
; shoot
If enemy()\firewait<1
If (r(enemy()\y) = r(hero\y) And lineofsight(enemy()\x,hero\x,hero\y)) Or (r(enemy()\y) = r(hero\y)+1 And lineofsight(enemy()\x,hero\x,hero\y))
If enemy()\x > hero\x
shoot(enemy()\x, enemy()\y, -0.9, 0, Asc("."), #False)
ElseIf enemy()\x < hero\x
shoot(enemy()\x, enemy()\y, 0.9, 0, Asc("."), #False)
EndIf
enemy()\firewait = 30
EndIf
EndIf
If enemy()\firewait
enemy()\firewait - 1
EndIf
; move
x = enemy()\x
y = enemy()\y
;enemy()\x -0.5 +Random(100)/100.0
;enemy()\y -0.5 +Random(100)/100.0
If Random(3)=0 : enemy()\x -1 +Random(2) : EndIf
If Random(3)=0 : enemy()\y -1 +Random(2) : EndIf
If issolid(enemy()\x, enemy()\y)
enemy()\x = x
enemy()\y = y
ElseIf Not redraw
If r(enemy()\x) <> x Or r(enemy()\y) <> y
redraw=#True
EndIf
EndIf
;redraw=#True
Next
EndProcedure
Procedure draw()
;ClearConsole()
;drawlevel()
drawtxt(1,0,"HEALTH "+LSet( Left("|||||||||||||||||||||||||||",hero\energy), 10,"."))
; delete
ForEach enemy()
drawlevelxy(enemy()\x_prev, enemy()\y_prev)
Next
drawlevelxy(hero\x_prev,hero\y_prev)
drawlevelxy(hero\x_prev,hero\y_prev+1)
drawlevelxy(gun_x_prev,gun_y_prev)
ForEach shot()
drawlevelxy(shot()\x_prev, shot()\y_prev)
Next
; redraw
ForEach enemy()
drawtxt(enemy()\x, enemy()\y, Chr(enemy()\c))
Next
drawtxt(hero\x,hero\y,hero\sprite)
If Not issolid(hero\x+hero\look, hero\y)
If hero\weapon
drawtxt(hero\x+hero\look, hero\y, "_")
EndIf
EndIf
ForEach shot()
drawtxt(shot()\x, shot()\y, Chr(shot()\c))
Next
EndProcedure
Procedure sound(nr)
CompilerIf #no_sound
;
CompilerElse
Protected i.l
Select nr
Case 0; pick up
For i=0 To 3
Beep_(1000+i*200,8)
Next
Case 1; shoot rifle
For i=0 To 8
Beep_(1000+Random(10)*50-i*80,4)
Next
Case 2; shoot laser
For i=8 To 0 Step -1
Beep_(1000+i*120,6)
Next
Case 99; game over
Beep_( 234, 200 )
Beep_( 211, 200 )
Beep_( 187, 200 )
Beep_( 176, 200 )
Beep_( 187, 400 )
Beep_( 158, 400 )
Beep_( 79, 400 )
Case 100; victory
Beep_( 396, 83 )
Beep_( 440, 83 )
Beep_( 469, 83 )
Beep_( 528, 83 )
Beep_( 594, 166 )
Beep_( 792, 166 )
Beep_( 594, 166 )
Beep_( 792, 166 )
Beep_( 1584, 249 )
EndSelect
CompilerEndIf
EndProcedure
Procedure shoot(x.f, y.f, dx.f, dy.f, c.c, byhero)
AddElement(shot())
shot()\x = x
shot()\y = y
shot()\dx = dx
shot()\dy = dy
shot()\c = c
shot()\byhero = byhero
Select Chr(c)
Case "." :: sound(1)
Case "_" :: sound(2)
EndSelect
EndProcedure
Procedure getprevious()
hero\x_prev = r(hero\x)
hero\y_prev = r(hero\y)
gun_x_prev = hero\x + hero\look
gun_y_prev = hero\y
ForEach enemy()
enemy()\x_prev = r(enemy()\x)
enemy()\y_prev = r(enemy()\y)
Next
ForEach shot()
shot()\x_prev = r(shot()\x)
shot()\y_prev = r(shot()\y)
Next
EndProcedure
OpenConsole()
; If 0 ; print ascii table
; Define i
; For i=30 To 256 : Print(Chr(i)) : Next
; For i=0 To 256 : PrintN(Str(i)+" "+Chr(i)) : Next
; Input()
; End
; EndIf
EnableGraphicalConsole(1)
ConsoleCursor(0)
loadlevel(?map01)
hero\x=4
hero\y=16
hero\isjumping=#True
hero\look=1
hero\energy=10
hero\sprite = "o"+#LF$
hero\sprite + "A"
;hero\weapon=2
ClearConsole()
drawlevel()
Repeat
Inkey()
If RawKey()
Select RawKey()
Case 37 ;{ left
hero\look = -1
If Not issolid(hero\x-1,hero\y) And Not issolid(hero\x-1,hero\y+1)
hero\x-1
If Not issolid(hero\x,hero\y+2)
hero\isjumping = #True
EndIf
redraw=#True
EndIf
;}
Case 39 ;{ right
hero\look = 1
If Not issolid(hero\x+1,hero\y) And Not issolid(hero\x+1,hero\y+1)
hero\x+1
If Not issolid(hero\x,hero\y+2)
hero\isjumping = #True
EndIf
redraw=#True
EndIf
;}
Case 38 ;{ up
If Not hero\isjumping
hero\isjumping = #True
hero\jump = #jump_init
EndIf
;}
Case 17 ;{ shoot
Select hero\weapon
Case 1 :: shoot(hero\x+hero\look, hero\y, 0.9 * hero\look, 0, Asc("."), #True)
Case 2 :: shoot(hero\x+hero\look, hero\y, 0.9 * hero\look, 0, Asc("_"), #True)
EndSelect
;}
Case Asc("Q") ;quit
quit = #True
EndSelect
EndIf
Select Chr(levelmap(Int(hero\x),Int(hero\y+1)))
Case ","
sound(0)
hero\weapon = 1
levelmap(Int(hero\x),Int(hero\y+1)) = 32
Case "_"
sound(0)
hero\weapon = 2
levelmap(Int(hero\x),Int(hero\y+1)) = 32
EndSelect
enemies()
jump()
bullets()
draw()
Delay(50)
getprevious()
If hero\energy<=0
drawtxt(32,12," ----------- "+#LF$+"| GAME OVER |"+#LF$+" ----------- ")
sound(99)
Delay(1000)
End
EndIf
If ListSize(enemy())=0
drawtxt(32,12," ----------- "+#LF$+"| VICTORY |"+#LF$+" ----------- ")
sound(100)
Delay(1000)
End
EndIf
Until quit
DataSection
map01:
Data.s " "
Data.s " ############################################################################## "
Data.s " # # "
Data.s " # = # "
Data.s " # = ## ## # "
Data.s " # = # "
Data.s " # ## ## = # "
Data.s " # ## ## # "
Data.s " # # "
Data.s " # _ # "
Data.s " # ######## = # "
Data.s " # # "
Data.s " # ###### # "
Data.s " ######### ################ ######### # "
Data.s " # # "
Data.s " # = ## # "
Data.s " # ## = = # "
Data.s " # # "
Data.s " # # "
Data.s " # , #### = # "
Data.s " # #### ########## #### # "
Data.s " # #### #### # "
Data.s " # #### #### # "
Data.s " ############################################################################## "
Data.s #LF$
map01end:
EndDataSection




