Miten saada vihollinen vahingoittamaan pelaajaa?

Voit pyytää apua ohjelmointiongelmiin täältä.
Post Reply
User avatar
Akuji
Member
Posts: 60
Joined: Fri Oct 08, 2010 5:59 pm
Location: Turku

Miten saada vihollinen vahingoittamaan pelaajaa?

Post by Akuji »

Minulla on tässä nyt pieni ongelma. Olen tekemässä räiskintäpeliä, jossa pelaajan pitää ampua vihollisia. Pelaaja kyllä pystyy ampumaan vihollisia, jolloin ne "deletoituvat". Ongelma on sitten siinä, etten mitenkään saa vihollista haavoittamaan pelaajaa, jolloin pelaaja deletoituu vihollisen sitä koskettaessa. Olen kokeillut melkein kaikkea, minkä tiedän, olenhan melkein aloittelija ;)
Kysyn siksi, että tämä on vaivannut minua jo aika pitkään enkä ole löytänyt tähän vastausta täältä ennen. Olisin todella kiitollinen, jos saisin tähän apua. Vaikka pieni koodinpätkä kelpaa hyvin.
User avatar
Frozen
Advanced Member
Posts: 282
Joined: Fri Jan 01, 2010 4:46 pm
Location: Suomi

Re: Miten saada vihollinen vahingoittamaan pelaajaa?

Post by Frozen »

Laita pelaajan hahmolle oma health arvo.

Code: Select all

omaukkeli=loadobject("media\guy.bmp",72)
vihollismuuttuja=loadobject("media\guy.bmp",72)

Health=100
repeat
If distance2(omaukkeli,vihollismuuttuja)<32 then
Health=Health-1
endif
If Health<0 then
'tähän sitten se kuolemis tapa mitä aiotkaan käyttää, animaatio yms. 
endif
Image
Työn alla:
Jotakin epäjulkaistua
User avatar
Akuji
Member
Posts: 60
Joined: Fri Oct 08, 2010 5:59 pm
Location: Turku

Re: Miten saada vihollinen vahingoittamaan pelaajaa?

Post by Akuji »

Koetin laittaa tuota koodia peliini, mutta en tiedä missä vika on. :?: Onko luultavasti koodini hieman erilainen vai missä vika. Tässä on siis koodini:

Code: Select all

FrameLimit 40

playerpoints = 0
font = LoadFont("arial",15)
fond= LoadFont("arial narrow,14")
SetFont font


SetFont fond
Locate 10,60
Color cborange
AddText "Target points: 25"
Locate 10,80
Color cborange
AddText "Points="





// Luodaan tyyppikokoelma ammuksia varten
Type BULLETS
    Field obj
End Type 

// Ladataan media
GoSub LoadMedia

// Määritetään tyyppikokoelma vihollisille ja luodaan pari vihollista
Type ENEMIES
    Field obj
    Field energy
End Type
GoSub MakeEnemies



'GoSub MakeEnemies



/////// PÄÄSILMUKKA ///////
Repeat
    GoSub CheckButtons
    GoSub EnemyAI
    GoSub CheckBullets
    GoSub DrawGUI
        
    // Siirretään kameraa pelaajan mukana
    CloneCameraPosition player
    
    // Tarkistetaan onko taustamusiikki pysähtynyt ja käynnistetään tarvittaessa uudelleen
    If SoundPlaying(backgroundmusic) = 0 Then
        backgroundmusic = PlaySound("Mission\battle1.xm", 100)
    EndIf
    If KeyHit(cbkeyF) Then ClearText
    
    DrawScreen 



Until KeyHit(cbkeyE)





/////// ALIOHJELMAT ///////
// Aliohjelma jossa ladataan pelissä tarvittava media
LoadMedia:
    // Ladataan kartta ja animoidaan se
    map = LoadMap("media\cdm2.til", "Media\tileset.bmp")
    PlayObject map,0,0,1.5
    PositionObject map, 0,0
    MaskObject map, cbmagenta
    
    grass=MakeObjectFloor()
PaintObject grass,LoadImage("media\grass.bmp")
'Make it run as it were far away 
PositionObject grass,0,0, 0

bullet=LoadObject("media\bigbullet.bmp")
PositionObject bullet,0,300

    
    // Ladataan panosobjektin grafiikat ja piilotetaan objekti
    bulletobject = LoadObject("media\bigbullet.bmp", 72)
    ShowObject bulletobject, OFF
    
    // Ladataan pelaaja ja asetetaan törmäyksentunnistus kartan seinien ja pelaaja välille
    player = LoadObject("media\soldier.bmp", 72)
    SetupCollision player,map,1,4,2
    
    ukko=LoadObject("media\guy.bmp",72)
    SetupCollision ukko,player,2,2,2
    PositionObject ukko,0,0
    
    // Ladataan vihollinen ja piilotetaan objekti
    enemyobject = LoadObject("media\ukkeli2.bmp", 72)
    ShowObject enemyobject, OFF
    
   
    
    // Ladataan äänet
    backgroundmusic = PlaySound("media\battle1.xm", 100)
    shot = LoadSound("media\rifle1.wav")
    scream = LoadSound("media\dragon.wav")
    Kävele = LoadSound ("media\walk.wav")
    hit= LoadSound ("media\kimpo1.wav")
    pain= LoadSound ("media\paino.wav")
    
    
    
Return

// Aliohjelma joka tarkistaa näppäinpainallukset
CheckButtons:
    If UpKey() Then MoveObject player,2
    If DownKey() Then MoveObject player,-0.8
    If LeftKey() Then TurnObject player,5
    If RightKey() Then TurnObject player,-5
    If KeyDown(cbkeyA) Then MoveObject player,0,-1  
    If KeyDown(cbkeyD) Then MoveObject player,0,1  
    
  
   
    'Voidaanko ampua
    If KeyDown(cbKeyup) And reload=0 Then
        PlaySound kävele,30
        reload=70 'lataa 1/4 sekunnissa (koska framelimit 40)
    EndIf
    'lataaminen
    If reload>0 Then reload-1
    
    'Voidaanko ampua
    If KeyDown(cbKeyDOWN) And reload=0 Then
        PlaySound kävele,30
        reload=110 'lataa 1/4 sekunnissa (koska framelimit 40)
    EndIf
    'lataaminen
    If reload>0 Then reload-1
    
    If KeyHit(cbkeyT) Then
    DeleteObject bullet
    EndIf
    
    
    // Tarkistetaan painetaanko ampumisnäppäintä ja jos, 
    // niin luodaan ammus ja törmäystunnistus sille
    If KeyHit(cbkeySpace) Then
        PlaySound shot, 80
        blt.BULLETS = New(BULLETS)
        blt\obj = CloneObject(bulletobject)
        CloneObjectPosition blt\obj, player
        CloneObjectOrientation blt\obj, player
        MoveObject blt\obj,15
        SetupCollision blt\obj,map,2,4,1
        ResetObjectCollision blt\obj
    EndIf
Return



// Aliohjelma, jossa tehdään viholliselle alkeellinen tekoäly
EnemyAI:
    For enem.ENEMIES = Each ENEMIES
        // Tarkistetaan näkeekö vihollisobjekti pelaajaobjekti ja
        // jos näkee niin aloitetaan liikuttamaan pelaajaa kohti
        If ObjectSight(enem\obj,player) Then
            PointObject enem\obj, player
            MoveObject enem\obj, 0.9
        EndIf
    Next enem

If ObjectSight(ukko,player) Then
RotateObject ukko,26
MoveObject ukko,1.5
EndIf


Return

// Aliohjelma, jossa läpikäydään ammukset
CheckBullets:
    For blt.BULLETS = Each BULLETS
        MoveObject blt\obj, 30
        For enem.ENEMIES = Each ENEMIES
            // Tarkistetaan osuuko ammus viholliseen
            If ObjectsOverlap(blt\obj, enem\obj, 2) Then
                deleteobj = 1               
                PlaySound pain,100
                enem\energy = enem\energy -50
                 playerpoints = playerpoints + 1
                
            EndIf
            
        Next enem
        bulcollisions = CountCollisions(blt\obj)
        For i = 1 To bulcollisions
            // Tarkistetaan onko ammus osunut seinään
            If GetCollision(blt\obj, i) > 1 Then deleteobj = 1
       PlaySound hit,100
        Next i
        If deleteobj = 1 Then
            DeleteObject blt\obj
            Delete blt
            deleteobj = 0
        EndIf
    Next blt





Return

// Aliohjelma jossa piirretään "käyttöliittymä"
DrawGUI:
    DrawGame
    DrawToWorld ON
    // Käydään viholliset läpi
    For enem.ENEMIES = Each ENEMIES
        PosX = ObjectX(enem\obj) - (ObjectSizeX(enem\obj)/2)
        PosY = ObjectY(enem\obj) + ObjectSizeY(enem\obj)
       
       
        Box PosX+1,PosY-1,EnWidth-2,4
        If enem\energy <= 0 Then
            // Jos energia nollassa, niin toistetaan huuto ja poistetaan vihollistyyppi
            PlaySound scream,100
            DeleteObject enem\obj
            Delete enem            
        StopSound backgroundmusic
        DeleteSound backgroundmusic
        Wait 3500
        GoTo over
        EndIf
        
    Next enem
    DrawToWorld OFF
    
    // Kirjoitetaan pisteet näytölle (ensimmäinen on varjostus)
    Color cbBlack : Text 61,81, playerpoints
    Color cbgreen : Text 60,80, playerpoints
    
Return

// Aliohjelma, jossa määritetään kaikki viholliset ja niiden energia
MakeEnemies:
    enem.ENEMIES = New(ENEMIES)
    enem\obj = CloneObject(enemyobject)
    PositionObject enem\obj,0,400
    SetupCollision enem\obj,map,2,4,1
    SetupCollision enem\obj,player,2,2,2
    SetupCollision player,enem\obj,2,2,2
    ResetObjectCollision enem\obj
    enem\energy = 2000
    
   
    
Return

over:
Tähän räiskintäpelirunkoon siis pitäisi saada pelaajalle oma healtti... Eli tarkemmin, kun vihollinen ja pelaaja törmäävät, pelaajan healtti vähenee.
Awaclus
Forum Veteran
Posts: 2939
Joined: Tue Aug 28, 2007 2:50 pm

Re: Miten saada vihollinen vahingoittamaan pelaajaa?

Post by Awaclus »

Code: Select all

    For enem.ENEMIES = Each ENEMIES
        // Tarkistetaan näkeekö vihollisobjekti pelaajaobjekti ja
        // jos näkee niin aloitetaan liikuttamaan pelaajaa kohti
        If ObjectSight(enem\obj,player) Then
            PointObject enem\obj, player
            MoveObject enem\obj, 0.9
        EndIf
        If ObjectsOverlap (enem\obj,player) Then Health-1
        If Health <1 Then MakeError "Lolol kuolit"
    Next enem
Lisäsin pari riviä (huomannet varmaan, mitkä) tuohon vihollisten tekoälykohtaan. Sitten vain lisäät koodisi alkuun Health=100 tai minkä verran sitten healthin haluatkaan olevan ja korvaat MakeErrorin jollain älykkäämmällä tavalla ilmoittaa siitä, että peli loppui.
User avatar
Akuji
Member
Posts: 60
Joined: Fri Oct 08, 2010 5:59 pm
Location: Turku

Re: Miten saada vihollinen vahingoittamaan pelaajaa?

Post by Akuji »

Jepjep. Kiitti! Nyt toimii!!! :D
User avatar
Akuji
Member
Posts: 60
Joined: Fri Oct 08, 2010 5:59 pm
Location: Turku

Re: Miten saada vihollinen vahingoittamaan pelaajaa?

Post by Akuji »

Äskeinen toimi todella hyvin, kun oli taso, jossa on yksi vihollinen. Mutta sitten kun niitä on todella paljon, pelaajan kuolema viivästyy joka vihollisen tapon jälkeen muutamia sekunteja. Esim. tapan vihut yksi ja kaksi. Jos en tapa, ne tappavat pelihahmoni kahdessa sekunnissa. Sitten menen vihun kolme luo, ja annan sen tappaa itseni. Siihen menee 5 sekuntia. Mitenköhän saisi tämän viiveen ehkäistyä? Kaikkien vihujenhan pitäisi tappaa pelaaja siinä 2 sekunnissa.
Tässä koodipätkä tarpeen mukaan:

Code: Select all

// Aliohjelma, jossa tehdään viholliselle alkeellinen tekoäly
EnemyAI:
    For enem.ENEMIES = Each ENEMIES
        // Tarkistetaan näkeekö vihollisobjekti pelaajaobjekti ja
        // jos näkee niin aloitetaan liikuttamaan pelaajaa kohti
        If ObjectSight(enem\obj,player) Then
            PointObject enem\obj, player
            MoveObject enem\obj, 0.5
           If ObjectsOverlap (enem\obj,player) Then Health-5
        If Health <1 Then MakeError "GAME OVER - YOU DIED"
    
        EndIf
    Next enem
Return
JATothrim
Tech Developer
Tech Developer
Posts: 606
Joined: Tue Aug 28, 2007 6:46 pm
Location: Kuopio

Re: Miten saada vihollinen vahingoittamaan pelaajaa?

Post by JATothrim »

Akuji wrote:Äskeinen toimi todella hyvin, kun oli taso, jossa on yksi vihollinen. Mutta sitten kun niitä on todella paljon, pelaajan kuolema viivästyy joka vihollisen tapon jälkeen muutamia sekunteja. Esim. tapan vihut yksi ja kaksi. Jos en tapa, ne tappavat pelihahmoni kahdessa sekunnissa. Sitten menen vihun kolme luo, ja annan sen tappaa itseni. Siihen menee 5 sekuntia. Mitenköhän saisi tämän viiveen ehkäistyä? Kaikkien vihujenhan pitäisi tappaa pelaaja siinä 2 sekunnissa.
Tässä koodipätkä tarpeen mukaan:

Code: Select all

// Aliohjelma, jossa tehdään viholliselle alkeellinen tekoäly
EnemyAI:
    For enem.ENEMIES = Each ENEMIES
        // Tarkistetaan näkeekö vihollisobjekti pelaajaobjekti ja
        // jos näkee niin aloitetaan liikuttamaan pelaajaa kohti
        If ObjectSight(enem\obj,player) Then
            PointObject enem\obj, player
            MoveObject enem\obj, 0.5
           If ObjectsOverlap (enem\obj,player) Then Health-5
        If Health <1 Then MakeError "GAME OVER - YOU DIED"
    
        EndIf
    Next enem
Return
Hmm.. Mukava ratkoa tällainen probleema, koska tämä on juuri sitä peliohjelmointia. :) Mieti: jos vähennät Pelaajan henkeä aina kun jokin vihollinen koskee pelaajaan jo esittelmälläsi tavalla, vähennetään henkeä per koskeva vihulainen. Eli pelaaja kuolee sitä nopeammin mitä enemmän vihulaisia häneen koskee. Haluat kuitekin, että pelaaja menehtyy aina vakio ajassa. Näin ollen laske vihollisten päivitys loopissa moniko niistä koskee pelaajaan. (vaikka Pelaaja_Damage muuttujaan) Loopin jälkeen vasta vähennät pelaajan henkeä muuttujan mukaan. Nyt pelaaja kuolee samassa ajassa riippumatta siitä montako vihollista häneen koski.
Protip: "If Health <1 Then MakeError "GAME OVER - YOU DIED"" tarkistuksen ei tarvitse olla vihollis loopissa.
-On selkeästi impulsiivinen koodaaja joka...
ohjelmoi C++:lla rekursiivisesti instantioidun templaten, jonka jokainen instantiaatio instantioi sekundäärisen singleton-template-luokan, jonka jokainen instanssi käynistää säikeen tulostakseen 'jea'.
User avatar
Akuji
Member
Posts: 60
Joined: Fri Oct 08, 2010 5:59 pm
Location: Turku

Re: Miten saada vihollinen vahingoittamaan pelaajaa?

Post by Akuji »

Noniin, tämä auttoi. Kiitos. ;)
Post Reply