Make two planets attack each other

I’m trying to modify the Solar System tutorial with an avatar attacking simulation. I want the planets to go back and forth and attack each other. I just want to use a posInterval() to move the planet from point A to point B.

The problem I have is that the planets just swap places twice and stop. Here’s the chunk of the code that I added/changed. This is using the Solar System tutorial 4 for the model loading, but no spinning.

  def AttackEnemyPlanet(self, enemy):
    self.heroAttack = self.sun.posInterval(1, Vec3(5,0,0))
    self.heroGoBack = self.sun.posInterval(1, Vec3(-5,0,0))
    self.heroSequence = Sequence(self.heroAttack, self.heroGoBack)
    self.heroSequence.start()
  
  def AttackHeroPlanet(self, enemy):
    self.enemyAttack = self.sun.posInterval(1, Vec3(-5,0,0))
    self.enemyGoBack = self.sun.posInterval(1, Vec3(5,0,0))
    self.enemySequence = Sequence(self.enemyAttack, self.enemyGoBack)
    self.enemySequence.start()
    
  def loadSky(self):
    self.sky = loader.loadModel("models/solar_sky_sphere")

    self.sky.reparentTo(render)

    self.sky.setScale(40)

    self.sky_tex = loader.loadTexture("models/stars_1k_tex.jpg")

    self.sky.setTexture(self.sky_tex, 1)

  def attackEnemy(self, enemy):
        myChanceOfHit = randint(1, 100) #Grab a random number from 1 to 100
        myAttackPower = randint(1, self.attackPower) #Grab a random number from 1 to max hit
        
        if (myChanceOfHit <= self.chanceOfHit): #If the random number is less than the chance of hit (ex: 65 <= 80) then hit.
            enemy.health -= myAttackPower       #Decrease the health of the enemy and print the result.
            print self.name+" attacks "+enemy.name+" for "+str(myAttackPower)+" points, "+enemy.name+" health is now "+str(enemy.health)
            return True
        else:
            print self.name+" misses "+enemy.name #If the random number is greater than the chance of hit then it's a miss.
            return False
#end class world

#Create a Hero with 100 health, 5 max attack power, 85% chance of hit, and his name.
heroAvatar  = Avatar(100, 5, 85, "Hero")
#Create an Enemy with 80 health, 4 max attack power, 75% chance of hit, and his name.
enemyAvatar = Avatar(80, 4, 75, "Enemy")

#Loop through the simulation by checking each health and making sure it's above 0.
#If one is below 0 then someone lost.
while (heroAvatar.health > 0 and enemyAvatar.health > 0):
    didItHit = heroAvatar.attackEnemy(enemyAvatar)
    if (didItHit):
      heroAvatar.AttackEnemyPlanet(enemyAvatar)
    if(enemyAvatar.health > 0): #If the enemy is dead, he doesn't get to hit.
        didItHit = enemyAvatar.attackEnemy(heroAvatar)
        if (didItHit):
          enemyAvatar.AttackHeroPlanet(heroAvatar)

#Check to see who won and print the result.
if (heroAvatar.health > 0):
    print "Hero wins. Enemy loses!"
else:
    print "Enemy wins. Hero loses!"

run()

This isn’t all of it, I left out the useless stuff from the actual tutorial, but the AttackEnemyPlanet and AttackHeroPlanet are the two functions I need help with.

Thanks.

You’re defining two Pos Intervals for each planets and play them in a Sequence once…
The code does what it should do, the sequence executes the first Pos Interval (moving from anywhere to Pos(5,0,0) ). After the first interval is finished, the second Pos Interval is executed, which moves the Planet from Pos(5,0,0) to Pos(-5,0,0). When the second interval is finished there’s nothing more to do for the sequence, so it stops.

Try sequence.loop(1) instead of sequence.start(), this should let the sequence run over and over again in a loop.

That’s a step in the right direction. I thought if I called the sequence function over and over again it would always ‘reset’ itself. I guess not…

Right now the planets are just swapping places simultaneously. Is there a way to make a sequence run (planet 1 attacks planet 2) then run an animation for planet 2 to attack planet 1? I don’t want them to happen at the same time, just back and forth.

Use one sequence for both planets is one solution.

Do something like this:

Sequence(movePlanet1, movePlanet2, movePlanet1Back, movePlanet2back)
Sequence.loop(1)

Looking at what you want to do I’d stay away from intervals. I’ve never found them that helpful except for repetitive actions. Spining is the only place I’ve used them in a game.

I would use a task function. The asteroids tutorial although it’s in 2D shows how a task is used. It’s a lot more powerful than a interval and it will let you do your avatar stuff and attacking.

Learning how to use tasks will help you out a lot.

I use tasks in my program to control both movement and AI. You can set up pretty decent AI you just have to think of the rules you want.