Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: EppaBasic: Ammuntapeli

fergusq [06.01.2016 13:56:33]

#

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

Suomalainen Programming Knowledge [15.09.2016 18:00:28]

#

... Täytyy lukee kun tulee windowsille

fergusq [16.09.2016 16:06:24]

#

Suomalainen Programming Knowledge kirjoitti:

... Täytyy lukee kun tulee windowsille

En ymmärrä

Grez [16.09.2016 16:26:40]

#

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.

groovyb [16.09.2016 17:21:11]

#

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
Loop

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta