Tässä on EppaBasicilla toteutettu ammuntapeli, jonka väsäsin joskus. Pelissä pelaajan on tarkoitus tappaa vihollinen, joka ampuu kuolettavia ammuksia pelaajaa päin kaiken aikaa.
Pelien tekeminen EB:llä on jokseenkin haastavaa, sillä kielessä ei ole vaihtelevankokoisia taulukoita. Siksi ammusten määrä kentällä onkin koko ajan vakio. Uusi ammus korvaa vanhimman ammuksen.
Pelissä ammutaan Z-näppäimellä ja käytetään voimakenttää X-näppäimellä.
Peliä voi kokeilla livenä osoitteessa http://eppabasic.fi/#CEFL74.
' Ammuntapeli EppaBasicilla
' (C) Iikka Hauhio 2015
Dim KOKO_X = 500
Dim KOKO_Y = 600
WindowSize KOKO_X, KOKO_Y
CanvasSize KOKO_X, KOKO_Y
Dim tick = 0
Dim aika = Timer()
Dim voittoaika = -1
''' Vastuksen ominaisuudet '''
' Sijainti
Dim vastusX = KOKO_X/2
Dim vastusY = 50
Dim nopeusX = 2
' Koko
Dim vastuksenKoko = 20
' Elämät
Dim ELÄMIÄ = 1000
Dim elämät = ELÄMIÄ
''' Ihmispelaajan ominaisuudet ''''
Dim pelaajaX = KOKO_X/2
Dim pelaajaY = KOKO_Y-10
Dim NOPEUS = 3
Dim POMMI = 1000
Dim POMMIN_KESTO = 200
Dim POMMIN_KOKO = 200
Dim pomminLataus = 0
''' Ammukset '''
' Ammusten maksimimäärä pelissä
Dim AMMUKSIA = 20
' Taulukko kaikista pelissä olevista ammuksista
' Indeksi 1 : pelaaja (1 : tietokone, 2 : ihminen)
' Indeksi 2 : ammuksen numero
' Indeksi 3 : ominaisuus
' Ominaisuudet:
' 1 : x
' 2 : y
' 3 : x-nopeus
' 4 : y-nopeus
' 5 : tyyppi (0 : tavallinen, 1 : kimpoileva, 2 : heiluva)
' 6 : koko
' 7 : väri (0 : harmaa, 1 : punainen)
Dim ammukset As Number[2,AMMUKSIA,7]
' Aloittaa pelin alusta, jos hävittiin
Sub alusta()
tick = 0
aika = Timer()
vastusX = KOKO_X/2
vastusY = 50
nopeusX = 1
elämät = ELÄMIÄ
pelaajaX = KOKO_X/2
pelaajaY = KOKO_Y-10
pomminLataus = 0
For p = 1 To 2
For i = 1 To AMMUKSIA
ammukset[p,i,1] = 0
ammukset[p,i,2] = 0
Next i
Next p
EndSub
''' Apufunktiot '''
' Palauttaa kahden pisteen välisen etäisyyden
Function etäisyys(ax As Number, ay As Number, bx As Number, by As Number) As Number
Return Sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by))
EndFunction
''' Ammusfunktiot '''
' Siirtää ammuksia
Sub liikutaAmmuksia()
For p = 1 To 2
For i = 1 To AMMUKSIA
' Onko ammus pelissä mukana
If ammukset[p,i,1] <> 0 And ammukset[p,i,2] <> 0 Then
If p = 2 And ammukset[p,i,6] > 2 Then
ammukset[p,i,6] = ammukset[p,i,6]-0.1
EndIf
' Onko ammus heiluva
If ammukset[p,i,5] = 2 Then
' Liikuta ammusta heiluvasti
ammukset[p,i,2] = ammukset[p,i,2] + ammukset[p,i,4] + Sin(tick/5 Mod 360)*2
ammukset[p,i,1] = ammukset[p,i,1] + ammukset[p,i,3] + Cos(tick/5 Mod 360)*2
Else
' Liikuta ammusta normaalisti
ammukset[p,i,2] = ammukset[p,i,2] + ammukset[p,i,4]
ammukset[p,i,1] = ammukset[p,i,1] + ammukset[p,i,3]
EndIf
' Jos ammus on ruudun ulkopuolella
If ammukset[p,i,1] < 0 Or ammukset[p,i,1] > KOKO_X Or ammukset[p,i,2] < 0 Or ammukset[p,i,2] > KOKO_Y Then
If ammukset[p,i,5] = 1 Then
' Jos ammus kimpoilee seinistä, sen suunta vaihtuu
If ammukset[p,i,1] < 0 Or ammukset[p,i,1] > KOKO_X Then ammukset[p,i,3] = -ammukset[p,i, 4]
If ammukset[p,i,2] < 0 Or ammukset[p,i,2] > KOKO_Y Then ammukset[p,i,4] = -ammukset[p,i, 4]
Else
' Muulloin se vain häviää
ammukset[p,i,1] = 0
ammukset[p,i,2] = 0
EndIf
EndIf
Dim x = ammukset[p,i,1]
Dim y = ammukset[p,i,2]
' Osuttiinko pelaajaan
If p = 1 And etäisyys(x, y, pelaajaX, pelaajaY) < ammukset[p,i,6] Then
alusta
Return
EndIf
' Osuttiinko vastukseen
If p = 2 And etäisyys(x, y, vastusX, vastusY) < vastuksenKoko Then
If elämät > 0 Then
elämät = elämät-ammukset[p,i,6]/10
EndIf
EndIf
' Osuiko pommi ammukseen
If pomminLataus < 0 And p = 1 And etäisyys(x, y, pelaajaX, pelaajaY) < POMMIN_KOKO Then
ammukset[p,i,1] = 0
ammukset[p,i,2] = 0
EndIf
EndIf
Next i
Next p
EndSub
' Piirtää ammukset näytölle
Sub piirräAmmukset()
For p = 1 To 2
For i = 1 To AMMUKSIA
If ammukset[p,i,1] <> 0 And ammukset[p,i,2] <> 0 Then
If ammukset[p,i,7] = 0 Then
DrawColor 100, 100, 100
Else
DrawColor 255, 0, 0
EndIf
DrawCircle ammukset[p,i,1], ammukset[p,i, 2], ammukset[p,i,6]
EndIf
Next i
Next p
EndSub
Dim uusi As Integer[2]
uusi[1] = 2
uusi[2] = 2
' Ampuu uuden ammuksen
Sub ammu(pelaaja As Integer, x As Integer, y As Number, vx As Number, vy As Number, tyyppi As Integer, koko As Integer, väri As Integer)
ammukset[pelaaja,uusi[pelaaja],1] = x
ammukset[pelaaja,uusi[pelaaja],2] = y
ammukset[pelaaja,uusi[pelaaja],3] = vx
ammukset[pelaaja,uusi[pelaaja],4] = vy
ammukset[pelaaja,uusi[pelaaja],5] = tyyppi
ammukset[pelaaja,uusi[pelaaja],6] = koko
ammukset[pelaaja,uusi[pelaaja],7] = väri
uusi[pelaaja] = (uusi[pelaaja] + 1) Mod (AMMUKSIA + 1)
EndSub
''' Vastuksen funktiot '''
' Siirtää vastusta - vastuksen tekoäly
Sub liikutaVastusta()
' Vastus ei tee mitään jos se on kuollut
If elämät <= 0 Then
Return
EndIf
' Osuuko vastukseen pommi
If pomminLataus < 0 And etäisyys(vastusX, vastusY, pelaajaX, pelaajaY) < POMMIN_KOKO Then
elämät = elämät - 1
EndIf
' Joka kymmenes ticki, liiku ja ammu
If tick Mod 10 = 0 Then
vastusX = vastusX + nopeusX
If vastusX > KOKO_X/3*2 Then
nopeusX = -2
EndIf
If vastusX < KOKO_X/3 Then
nopeusX = 2
EndIf
If elämät > ELÄMIÄ*2/3 Then
'ammu 1, vastusX, vastusY, ((uusi[1] Mod 10) - 5)/3, 3, 0, 20, 1
If tick/10 Mod 5 = 0 Then
ammu 1, vastusX, vastusY, -1, 3, 0, 20, 1
ammu 1, vastusX, vastusY, -0.5, 3, 0, 20, 1
ammu 1, vastusX, vastusY, 0, 3, 0, 20, 1
ammu 1, vastusX, vastusY, 0.5, 3, 0, 20, 1
ammu 1, vastusX, vastusY, 1, 3, 0, 20, 1
EndIf
Else If elämät > ELÄMIÄ*1/3 Then
If uusi[1] Mod 2 = 0 Then
ammu 1, vastusX, vastusY, (pelaajaX-vastusX)/150, (pelaajaY-vastusY)/150, 0, 5, 1
Else
ammu 1, vastusX, vastusY, ((uusi[1] Mod 10) - 5)/3, 3, 0, 20, 1
EndIf
Else
ammu 1, vastusX, vastusY, ((uusi[1] Mod 10) - 5)/3, 3, 2, 20, 1
EndIf
EndIf
EndSub
' Piirtää vastuksen
Sub piirräVastus()
FillColor 255, 255, 255
FillCircle vastusX, vastusY, 20
FillColor 100,100,100
FillRect vastusX-20, vastusY, 10, 10
FillRect vastusX+10, vastusY, 10, 10
' Elämät
DrawColor 0,255,0
DrawLine 10, 10, elämät/ELÄMIÄ*(KOKO_X-20), 10
If elämät > ELÄMIÄ*2/3 Then
DrawLine 10, 10, 480*2/3, 10
Else If elämät > ELÄMIÄ*1/3 Then
DrawLine 10, 10, 480/3, 10
EndIf
EndSub
''' Ihmispelaajan funktiot '''
' Piirtää pelaajan
Sub piirräPelaaja()
' Jalat
DrawColor 255, 255, 255
DrawLine pelaajaX-2, pelaajaY+5, pelaajaX-2, pelaajaY+10
DrawLine pelaajaX+2, pelaajaY+5, pelaajaX+2, pelaajaY+10
' Vartalo
FillColor 255, 10, 10
FillTriangle pelaajaX, pelaajaY-2, pelaajaX-5, pelaajaY+7, pelaajaX+5, pelaajaY+7
FillRect pelaajaX - 2, pelaajaY - 6, 4, 8
' Pää
FillColor 255, 255, 200
FillCircle pelaajaX, pelaajaY-7, 4
' Hattu
FillColor 255, 10, 10
FillTriangle pelaajaX-4, pelaajaY-10, pelaajaX+4, pelaajaY-10, pelaajaX, pelaajaY-15
' Pommin lataus
DrawColor 0, 0, 255
FillColor 0, 0, 255
If pomminLataus < 0 Then
DrawCircle pelaajaX, pelaajaY, POMMIN_KOKO
Else
DrawLine 10, KOKO_Y-10, 10, KOKO_Y-10-pomminLataus/POMMI*(KOKO_Y/2-10)
If pomminLataus = POMMI Then FillCircle 10, KOKO_Y/2, 10
EndIf
' Aika
TextAlign 2
TextSize 15
If voittoaika < 0 Then
DrawText KOKO_X-10, KOKO_Y-25, Floor(Timer()-aika) & " sekuntia"
Else
DrawText KOKO_X-10, KOKO_Y-25, Floor(voittoaika-aika) & " sekuntia"
EndIf
EndSub
' Liikuttaa pelaajaa (lukee syötettä)
Sub liikutaPelaajaa()
If KeyDown(ebKeyUp) And pelaajaY - NOPEUS > 0 Then
pelaajaY = pelaajaY - NOPEUS
Else If KeyDown(ebKeyDown) And pelaajaY + NOPEUS < KOKO_Y Then
pelaajaY = pelaajaY + NOPEUS
Else If KeyDown(ebKeyLeft) And pelaajaX - NOPEUS > 0 Then
pelaajaX = pelaajaX - NOPEUS
Else If KeyDown(ebKeyRight) And pelaajaX + NOPEUS < KOKO_X Then
pelaajaX = pelaajaX + NOPEUS
EndIf
If KeyDown(ebKeyZ) And tick Mod 10 = 0 Then
ammu 2, pelaajaX-10, pelaajaY, 0, -10, 0, 10, 0
ammu 2, pelaajaX+10, pelaajaY, 0, -10, 0, 10, 0
ammu 2, pelaajaX-10, pelaajaY, -1, -10, 0, 10, 0
ammu 2, pelaajaX+10, pelaajaY, 1, -10, 0, 10, 0
EndIf
If KeyHit(ebKeyX) And pomminLataus >= POMMI Then
pomminLataus = -POMMIN_KESTO
EndIf
If pomminLataus < POMMI Then pomminLataus = pomminLataus + 1
EndSub
' Pääsilmukka
Do
If elämät <= 0 Then
voittoaika = Timer()
EndIf
ClearScreen
piirräVastus
piirräAmmukset
piirräPelaaja
DrawScreen
liikutaVastusta
liikutaAmmuksia
liikutaPelaajaa
tick = tick + 1
Loop... Täytyy lukee kun tulee windowsille
Suomalainen Programming Knowledge kirjoitti:
... Täytyy lukee kun tulee windowsille
En ymmärrä
Mäkään en ymmärtänyt että pitäiskö tossa jotain tapahtua. Kun sitä vihulaista on tarpeeksi kauan ampunut niin se vaan lopettaa ampumisen ja hyytyy paikalleen. Onko se sit niinkuin läpi pelattu?
Viitaten esittelyyn, en myöskään ihan ymmärrä mikä merkittävä helpotus koodaamiseen olisi ollut muuttuvan kokoisista taulukoista.
Ei siinä oikein voi tapahtua mitään kun tuo pallon elämät menee nolliin, jos vaan jatketaan samaa piirtämistä.
Pääsilmukan tulisi olla jotain tän suuntaista, jos haluaisi parempaa infoa voitosta
' Pääsilmukka
Do
If elämät <= 0 Then
ClearScreen
DrawText KOKO_X-150, KOKO_Y-150,"Voitit!"
DrawScreen
else
ClearScreen
piirräVastus
piirräAmmukset
piirräPelaaja
DrawScreen
liikutaVastusta
liikutaAmmuksia
liikutaPelaajaa
tick = tick + 1
endif
LoopAihe on jo aika vanha, joten et voi enää vastata siihen.