2
回答
按照书上的代码写,但是好像没有用到Bullet类,求解。。。
华为云实践训练营,热门技术免费实践!>>>   
#精灵库文件
import pygame,sys,random,math,time
from pygame.locals import*
def print_text(font,x,y,text,color=(255,255,255)):
    imgText=font.render(text,True,color)
    screen=pygame.display.get_surface()
    screen.blit(imgText,(x,y))
class MySprite(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self) #extend the base sprite class
        self.image=None
        self.frame=0
        self.old_frame=-1
        self.frame_width=1
        self.frame_height=1
        self.first_frame=0
        self.last_frame=0
        self.columns=1
        self.last_time=0
        self.velocity=point(0,0)
    #x property

    def _getx(self):
        return self.rect.x
    def _setx(self,value):
        self.rect.x=value
    X=property(_getx,_setx)
    #y property
    def _gety(self):
        return self.rect.y
    def _sety(self,value):
        self.rect.y=value
    Y=property(_gety,_sety)

    #position property
    def _getpos(self):
        return self.rect.topleft
    def _setpos(self,pos):
        self.rect.topleft =pos
    position=property(_getpos,_setpos)

    def load(self,filename,width=0,height=0,columns=1):
        self.image=pygame.image.load(filename).convert_alpha()
        self.set_image(self.image,width,height,columns)
    def set_image(self,image,width=0,height=0,columns=1):
        self.image= image
        if width==0 and height==0:
            self.frame_width=image.get_width()
            self.frame_height=image.get_height()
        else:
            self.frame_width=width
            self.frame_height=height
            rect=self.image.get_rect()
            self.last_frame=(rect.width//width)*(rect.height//height)-1
        self.rect=Rect(0,0,self.frame_width,self.frame_height)
        self.columns=columns

    def update(self,current_time,rate=30):
        if self.last_frame>self.first_frame:
            #update animation frame nunber
            if current_time>self.last_time+rate:
                self.frame+=1
                if self.frame>self.last_frame:
                    self.frame=self.first_frame
                self.last_time=current_time
            else:
                self.frame=self.first_frame



#point class
class point(object):
    def __init__(self,x,y):
        self.__x=x
        self.__y=y
    #X property
    def getx(self):
        return self.__x
    def setx(self,x):
        self.__x=x
    x=property(getx,setx)
    #y property
    def gety(self):
        return self.__y
    def sety(self,y):
        self.__y=y
    y=property(gety,sety)

    def __str__(self):
        return "{X:"+"{:.0f}".format(self.__x)+",Y"+"{:.0f}".format(self.__y)+"}"
    

#calculates angle between two points
def target_angle(x1,y1,x2,y2):
    delta_x = x2-x1
    delta_y = y2-y1
    angle_radians=math.atan2(delta_y,delta_x)
    angle_degrees=math.degrees(angle_radians)
    return angle_degrees
def wrap_angle(angle):
    return abs(angle%360)

这个是书上的坦克游戏的代码,按理是按空格键的时候会发射子弹,敌方的坦克每隔1S发射子弹,但是好没有用到Bullet类,问题说是  name 'enemy_fire_cannon' is not defined  比较困扰,请求解答。。

import sys,time,random,math,pygame
from pygame.locals import *
from mylibrary import *
class Tank(MySprite):
    def __init__(self,tank_file="tank.png",turret_file="turret.png"):
        MySprite.__init__(self)
        self.load(tank_file,30,26,1)
        self.speed=0.0
        self.scratch=None
        self.float_pos=point(0,0)
        self.velocity=point(0,0)
        self.turret=MySprite()
        self.turret.load(turret_file,17,15,1)
        self.fire_timer=0
        self.rotation=0
    def update(self,ticks):
        #update chassis
        MySprite.update(self,ticks,100)
        self.rotation=wrap_angle(self.rotation)
        self.scratch=pygame.transform.rotate(self.image,-self.rotation)
        angle=wrap_angle(self.rotation-90)
        self.velocity=angular_velocity(angle)
        self.float_pos.x+=self.velocity.x
        self.float_pos.y+=self.velocity.y
        

        if self.float_pos.x<-30 : self.float_pos.x=800
        elif self.float_pos.x>800: self.float_pos.x=-30
        if self.float_pos.y <-10 :self.float_pos.y=600
        elif self.float_pos.y>600 :self.float_pos.y=-10

        #transfer float into int
        self.X=int(self.float_pos.x)
        self.Y=int(self.float_pos.y)

        #update turret
        self.turret.position=(self.X,self.Y)
        self.turret.last_frame=0
        self.turret.update(ticks,100)
        self.turret.rotation=wrap_angle(self.turret.rotation)
        angle=self.turret.rotation+90
        self.turret.scratch=pygame.transform.rotate(self.turret.image,-angle)
    def draw(self,surface):
        #draw chassis--s
        width,height=self.scratch.get_size()
        center=point(width/2,height/2)
        surface.blit(self.scratch,(self.X-center.x,self.Y-center.y))
        #draw turret
        width,height=self.turret.scratch.get_size()
        center=point(width/2,height/2)
        surface.blit(self.turret.scratch,(self.turret.X-center.x,self.turret.Y-center.y))
    def __str__(self):
        return MySprite.__str__(self)+","+str(self.velocity)
class EnemyTank(Tank):
    def __init__(self,tank_file="tank.png",turret_file="turret.png"):
        Tank.__init__(self,tank_file,turret_file)
    def update(self,ticks):
        self.turret.rotation=wrap_angle(self.rotation-90)
        Tank.update(self,ticks)
    def draw(self,surface):
        Tank.draw(self,surface)
class Bullet():
    def __init__(self,position):
        self.alive=True
        self.color=(255,20,20)
        self.position=point(position.x,position.y)
        self.velocity=point(0,0)
        self.rect=Rect(0,0,4,4)
        self.owner= ""
    def update(self,ticks):
        self.position.x+=self.velocity.x*10
        self.position.y+=self.velocity.y*10
        if self.position.x <0 or self.position.x >800 or self.position.y<0 or self.position.y>600:
            self.alive=False
        self.rect=Rect(self.position.x,self.position.y,4,4)
    def draw(self,surface):
        pos=(int(self.position.x),int(self.position.y))
        pygame.draw.circle(surface,self.color,pos,4,0)
    def fire_cannon(tank):
        position=point(tank.turret.X,tank.turret.Y)
        bullet=Bullet(position)
        angle=tank.turret.rotation
        bullet.velocity=angular_velocity(angle)
        bullets.append(bullet)
        return bullet
    def player_fire_cannon():
        bullet=fire_cannon(player)
        bullet.owner="player"
        bullet.color=(30,250,30)
    def enemy_fire_cannon():
        bullet=fire_cannon(enemy_tank)
        bullet.owner="enemy"
        bullet.color=(250,30,30)

def angular_velocity(angle):
       vel=point(0,0)
       vel.x=math.cos(math.radians(angle))
       vel.y=math.sin(math.radians(angle))
       return vel
def game_init():
    global screen,backbuffer,font,timer,player_gruop,player,enemy_tank,bullets,crosshair,crosshair_group,position

    pygame.init()
    screen=pygame.display.set_mode((800,600))
    backbuffer=pygame.Surface((800,600))
    pygame.display.set_caption("Tank game")
    font=pygame.font.Font(None,30)
    timer=pygame.time.Clock()
    pygame.mouse.set_visible(False)

    #load mouse cursor
    crosshair=MySprite()
    crosshair.load("crosshair.png")
    crosshair_group=pygame.sprite.GroupSingle()
    crosshair_group.add(crosshair)

    #creat player tank
    player=Tank()
    player.float_pos=point(400,300)

    #creat enemy tank
    enemy_tank=EnemyTank()
    
    enemy_tank.float_pos=point(random.randint(50,760),50)
    enemy_tank.rotation=135

    #creat bullet
    bullets=list()
#main program
game_init()
game_over=False
player_score=0
enemy_score=0
last_time=0
mouse_x=mouse_y=0
#main loop
while 1:
    timer.tick(30)
    ticks=pygame.time.get_ticks()

    #reser mouse state variables
    mouse_up=mouse_down=0
    mouse_up_x=mouse_up_y=0
    mouse_down_x=mouse_down_y=0
    #event section
    for event in pygame.event.get():
        if event.type==QUIT: sys.exit()
        elif event.type==MOUSEMOTION:
            mouse_x,mouse_y=event.pos
            move_x,move_y=event.rel
        elif event.type==MOUSEBUTTONDOWN:
            mouse_down=event.button
            mouse_down_x,mouse_down_y=event.pos
        elif event.type==MOUSEBUTTONUP:
            mouse_up=event.button
            mouse_up_x,mouse_up_y=event.pos
    #get key states
    keys=pygame.key.get_pressed()
    if keys[K_ESCAPE]: sys.exit()
    elif keys[K_LEFT] or keys[K_a]:
        #calculate new diretion
        player.rotation-=2.0
    elif keys[K_RIGHT] or keys[K_d]:
        player.rotation+=2.0
        
    #fire connon
    if keys[K_SPACE] or mouse_up >0:
        if ticks>player.fire_timer +1000:
            player.fire_timer=ticks
            player_fire_cannon()
    #update section
    if not game_over:
        crosshair.position=(mouse_x,mouse_y)
        crosshair_group.update(ticks)
    #point tank turret toward crosshair
    angle=target_angle(player.turret.X,player.turret.Y,crosshair.X+crosshair.frame_width/2,crosshair.Y+crosshair.frame_height/2)
    player.turret.rotation=angle

    #move tank
    player.update(ticks)
    #update enemies
    enemy_tank.update(ticks)
    if ticks>enemy_tank.fire_timer+1000:
        enemy_tank.fire_timer=ticks
        enemy_fire_cannon()
    for bullet in bullets:
        bullet.update(ticks)
        if bullet.owner == "player":
               if pygame.sprite.collide_rect(bullet,enemy_tank):
                      player_score+=1
                      bullet.alive=False
        elif bullet.owner == "enemy": 
               if pygame.sprite.collide_rect(bullet,player):
                      enemy_score+=1
                      bullet.alive=False
                     
                     
              

    #draw section
    backbuffer.fill((100,100,20))

    for bullet in bullets:
        bullet.draw(backbuffer)
    enemy_tank.draw(backbuffer)
    player.draw(backbuffer)

    screen.blit(backbuffer,(0,0))
    if not game_over:
        print_text(font,0,0,"player"+"score"+str(player_score))
        print_text(font,700,0,"enemy"+"score"+str(enemy_score))
    else:
        print_text(font,0,0,"game over")


    pygame.display.update()
    #remove expired bullets
    for bullet in bullets:
        if bullet.alive==False:
            bullets.remove(bullet)



比较小白。。谢谢大家。。^_^



举报
eeeeecoey
发帖于2年前 2回/227阅
顶部