PYGAME EXAMPLE 2

Tank Battle Game:

<pre>

Tank Battle Game

Chapter 12

import sys, time, random, math, pygame
from pygame.locals import *
from MyLibrary import *

class Bullet():
def init(self,position):
self.alive = True
self.color = (250,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.0
    self.position.y += self.velocity.y \* 10.0
    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)
play_sound(shoot_sound)
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)

class Tank(MySprite):
def init(self,tank_file="tank.png",turret_file="turret.png"):
MySprite.init(self)
self.load(tank_file, 50, 60, 4)
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, 32, 64, 4)
self.fire_timer = 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

    #warp tank around screen edges (keep it simple)
    if self.float_pos.x < -50: self.float_pos.x = 800
    elif self.float_pos.x > 800: self.float_pos.x = -50
    if self.float_pos.y < -60: self.float_pos.y = 600
    elif self.float_pos.y > 600: self.float_pos.y = -60

    #transfer float position to integer position for drawing
    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 the chassis
    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 the 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="enemy_tank.png",turret_file="enemy_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)

this function initializes the game

def game_init():
global screen, backbuffer, font, timer, player_group, player,
enemy_tank, bullets, crosshair, crosshair_group

pygame.init()
screen = pygame.display.set_mode((800,600))
backbuffer = pygame.Surface((800,600))
pygame.display.set_caption("Tank Battle 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)

#create player tank
player = Tank()
player.float_pos = Point(400,300)

#create enemy tanks
enemy_tank = EnemyTank()
enemy_tank.float_pos = Point(random.randint(50,760), 50)
enemy_tank.rotation = 135

#create bullets
bullets = list()

this function initializes the audio system

def audio_init():
global shoot_sound, boom_sound

#initialize the audio mixer
pygame.mixer.init() 

#load sound files
shoot_sound = pygame.mixer.Sound("shoot.wav")
boom_sound = pygame.mixer.Sound("boom.wav")

this function uses any available channel to play a sound clip

def play_sound(sound):
channel = pygame.mixer.find_channel(True)
channel.set_volume(0.5)
channel.play(sound)

main program begins

game_init()
audio_init()
game_over = False
player_score = 0
enemy_score = 0
last_time = 0
mouse_x = mouse_y = 0

main loop

while True:
timer.tick(30)
ticks = pygame.time.get_ticks()

#reset 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 direction velocity
    player.rotation -= 2.0
    
elif keys[K_RIGHT] or keys[K_d]:
    #calculate new direction velocity
    player.rotation += 2.0

#fire cannon!
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() 

    #update bullets
    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
                play_sound(boom_sound)
        elif bullet.owner == "enemy":
            if pygame.sprite.collide_rect(bullet, player):
                enemy_score += 1
                bullet.alive = False
                play_sound(boom_sound)


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

for bullet in bullets:
    bullet.draw(backbuffer)

    enemy_tank.draw(backbuffer)

player.draw(backbuffer)

crosshair_group.draw(backbuffer)

screen.blit(backbuffer, (0,0))

if not game_over:
    print_text(font, 0, 0, "PLAYER " + str(player_score))
    print_text(font, 700, 0, "ENEMY " + 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)    

</pre>

Artillery Gunner:

<pre>

Artillery Gunner Game

Chapter 12

import sys, time, random, math, pygame
from pygame.locals import *
from MyLibrary import *

class Terrain():
def init(self, min_height, max_height, total_points):
self.min_height = min_height
self.max_height = max_height
self.total_points = total_points+1
self.grid_size = 800 / total_points
self.height_map = list()
self.generate()

def generate(self):
    #clear list
    if len(self.height_map)>0:
        for n in range(self.total_points):
            self.height_map.pop()
    
    #first point
    last_x = 0
    last_height = (self.max_height + self.min_height) / 2
    self.height_map.append( last_height )
    direction = 1
    run_length = 0
    
    #remaining points
    for n in range( 1, self.total_points ):
        rand_dist = random.randint(1, 10) \* direction
        height = last_height + rand_dist
        self.height_map.append( int(height) )
        if height < self.min_height: direction = -1
        elif height > self.max_height: direction = 1
        last_height = height
        if run_length <= 0:
            run_length = random.randint(1,3)
            direction = random.randint(1,2)
            if direction == 2: direction = -1
        else:
            run_length -= 1

def get_height(self,x):
    x_point = int(x / self.grid_size)
    return self.height_map[x_point]

def draw(self, surface):
    last_x = 0
    for n in range( 1, self.total_points ):
        #draw circle at current point
        height = 600 - self.height_map[n]
        x_pos = int(n \* self.grid_size)
        pos = (x_pos, height)
        color = (255,255,255)
        #pygame.draw.circle(surface, color, pos, 4, 1)
        if n == grid_point:
            pygame.draw.circle(surface, (0,255,0), pos, 4, 0)
        #draw line from previous point
        last_height = 600 - self.height_map[n-1]
        last_pos = (last_x, last_height)
        pygame.draw.line(surface, color, last_pos, pos, 2)
        last_x = x_pos

this function initializes the game

def game_init():
global screen, backbuffer, font, timer, crosshair, crosshair_group, terrain

pygame.init()
screen = pygame.display.set_mode((800,600))
backbuffer = pygame.Surface((800,600))
pygame.display.set_caption("Artillery Gunner Game")
font = pygame.font.Font(None, 30)
timer = pygame.time.Clock()

#create terrain
terrain = Terrain(50, 400, 100)

this function initializes the audio system

def audio_init():
global shoot_sound, boom_sound

#initialize the audio mixer
pygame.mixer.init() 

#load sound files
shoot_sound = pygame.mixer.Sound("shoot.wav")
boom_sound = pygame.mixer.Sound("boom.wav")

this function uses any available channel to play a sound clip

def play_sound(sound):
channel = pygame.mixer.find_channel(True)
channel.set_volume(0.5)
channel.play(sound)

these functions draw a cannon at the specified position

def draw_player_cannon(surface,position):
#draw turret
turret_color = (30,180,30)
start_x = position.x + 15
start_y = position.y + 15
start_pos = (start_x, start_y)
vel = angular_velocity( wrap_angle(player_cannon_angle-90) )
end_pos = (start_x + vel.x * 30, start_y + vel.y * 30)
pygame.draw.line(surface, turret_color, start_pos, end_pos, 6)
#draw body
body_color = (30,220,30)
rect = Rect(position.x, position.y+15, 30, 15)
pygame.draw.rect(surface, body_color, rect, 0)
pygame.draw.circle(surface, body_color, (position.x+15,position.y+15), 15, 0)

def draw_computer_cannon(surface,position):
#draw turret
turret_color = (180,30,30)
start_x = position.x + 15
start_y = position.y + 15
start_pos = (start_x, start_y)
vel = angular_velocity( wrap_angle(computer_cannon_angle-90) )
end_pos = (start_x + vel.x * 30, start_y + vel.y * 30)
pygame.draw.line(surface, turret_color, start_pos, end_pos, 6)
#draw body
body_color = (220,30,30)
rect = Rect(position.x, position.y+15, 30, 15)
pygame.draw.rect(surface, body_color, rect, 0)
pygame.draw.circle(surface, body_color, (position.x+15,position.y+15), 15, 0)

main program begins

game_init()
audio_init()
game_over = False
player_score = 0
enemy_score = 0
last_time = 0
mouse_x = mouse_y = 0
grid_point = 0
player_score = computer_score = 0
player_cannon_position = Point(0,0)
player_cannon_angle = 45
player_cannon_power = 8.0
computer_cannon_position = Point(0,0)
computer_cannon_angle = 315
computer_cannon_power = 8.0
player_firing = False
player_shell_position = Point(0,0)
player_shell_velocity = Point(0,0)
computer_firing = False
computer_shell_position = Point(0,0)
computer_shell_velocity = Point(0,0)

main loop

while True:
timer.tick(30)
ticks = pygame.time.get_ticks()

#event section
for event in pygame.event.get():
    if event.type == QUIT: sys.exit()
    elif event.type == MOUSEMOTION:
        mouse_x,mouse_y = event.pos
    elif event.type == MOUSEBUTTONUP:
        terrain.generate()

#get key states 
keys = pygame.key.get_pressed()
if keys[K_ESCAPE]: sys.exit()

elif keys[K_UP] or keys[K_w]:
    player_cannon_angle = wrap_angle( player_cannon_angle - 1 )
    
elif keys[K_DOWN] or keys[K_s]:
    player_cannon_angle = wrap_angle( player_cannon_angle + 1 )

elif keys[K_RIGHT] or keys[K_d]:
    if player_cannon_power <= 10.0:
        player_cannon_power += 0.1
    
elif keys[K_LEFT] or keys[K_a]:
    if player_cannon_power > 0.0:
        player_cannon_power -= 0.1

if keys[K_SPACE]:
    if not player_firing:
        play_sound(shoot_sound)
        player_firing = True
        angle = wrap_angle( player_cannon_angle - 90 )
        player_shell_velocity = angular_velocity( angle )
        player_shell_velocity.x \*= player_cannon_power
        player_shell_velocity.y \*= player_cannon_power
        player_shell_position = player_cannon_position
        player_shell_position.x += 15
        player_shell_position.y += 15
    

#update section
if not game_over:
    #keep turret inside a reasonable range
    if player_cannon_angle > 180:
        if player_cannon_angle < 270: player_cannon_angle = 270
    elif player_cannon_angle <= 180:
        if player_cannon_angle > 90: player_cannon_angle = 90
    

    #calculate mouse position on terrain
    grid_point = int(mouse_x / terrain.grid_size)

    #move player shell
    if player_firing:
        player_shell_position.x += player_shell_velocity.x
        player_shell_position.y += player_shell_velocity.y

        #has shell hit terrain?
        height = 600 - terrain.get_height(player_shell_position.x)
        if player_shell_position.y > height:
            player_firing = False

        if player_shell_velocity.y < 10.0:
            player_shell_velocity.y += 0.1

        #has shell gone off the screen?            
        if player_shell_position.x < 0 or player_shell_position.x > 800:
            player_firing = False
        if player_shell_position.y < 0 or player_shell_position.y > 600:
            player_firing = False


    #move computer shell
    if computer_firing:
        computer_shell_position.x += computer_shell_velocity.x
        computer_shell_position.y += computer_shell_velocity.y

        #has shell hit terrain?
        height = 600 - terrain.get_height(computer_shell_position.x)
        if computer_shell_position.y > height:
            computer_firing = False

        if computer_shell_velocity.y < 10.0:
            computer_shell_velocity.y += 0.1
        
        #has shell gone off the screen?
        if computer_shell_position.x < 0 or computer_shell_position.x > 800:
            computer_firing = False
        if computer_shell_position.y < 0 or computer_shell_position.y > 600:
            computer_firing = False
    else:
        #is the computer ready to fire?
        play_sound(shoot_sound)
        computer_firing = True
        computer_cannon_power = random.randint(1,10)
        angle = wrap_angle( computer_cannon_angle - 90 )
        computer_shell_velocity = angular_velocity( angle )
        computer_shell_velocity.x \*= computer_cannon_power
        computer_shell_velocity.y \*= computer_cannon_power
        computer_shell_position = computer_cannon_position
        computer_shell_position.x += 15
        computer_shell_position.y += 15

    #look for a hit by player's shell
    if player_firing:
        dist = distance(player_shell_position, computer_cannon_position)
        if dist < 30:
            play_sound(boom_sound)
            player_score += 1
            player_firing = False


    #look for a hit by computer's shell
    if computer_firing:
        dist = distance(computer_shell_position, player_cannon_position)
        if dist < 30:
            play_sound(boom_sound)
            computer_score += 1
            computer_firing = False
        


#drawing section
backbuffer.fill((20,20,120))

#draw the terrain
terrain.draw(backbuffer)

#draw player's gun
y = 600 - terrain.get_height(70+15) - 20
player_cannon_position = Point(70,y)
draw_player_cannon(backbuffer, player_cannon_position)

#draw computer's gun
y = 600 - terrain.get_height(700+15) - 20
computer_cannon_position = Point(700,y)
draw_computer_cannon(backbuffer, computer_cannon_position)

#draw player's shell
if player_firing:
    x = int(player_shell_position.x)
    y = int(player_shell_position.y)
    pygame.draw.circle(backbuffer, (20,230,20), (x,y), 4, 0)

#draw computer's shell
if computer_firing:
    x = int(computer_shell_position.x)
    y = int(computer_shell_position.y)
    pygame.draw.circle(backbuffer, (230,20,20), (x,y), 4, 0)

    
#draw the back buffer
screen.blit(backbuffer, (0,0))

if not game_over:
    print_text(font, 0, 0, "SCORE " + str(player_score))
    print_text(font, 0, 20, "ANGLE " + "{:.1f}".format(player_cannon_angle))
    print_text(font, 0, 40, "POWER " + "{:.2f}".format(player_cannon_power))
    if player_firing:
        print_text(font, 0, 60, "FIRING")
    print_text(font, 650, 0, "SCORE " + str(computer_score))
    print_text(font, 650, 20, "ANGLE " + "{:.1f}".format(computer_cannon_angle))
    print_text(font, 650, 40, "POWER " + "{:.2f}".format(computer_cannon_power))
    if computer_firing:
        print_text(font, 650, 60, "FIRING")

    print_text(font, 0, 580, "CURSOR " + str(Point(mouse_x,mouse_y)) + \
        ", GRID POINT " + str(grid_point) + ", HEIGHT " + \
        str(terrain.get_height(mouse_x)))
else:
    print_text(font, 0, 0, "GAME OVER")

pygame.display.update()

</pre>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容