Watch Star Fork

rocket049 / ship_gunnerPythonGPL-3.0

Sign up for free
Explore and code with more than 2 million developers,Free private repositories !:)
Sign up
模拟射击游戏,扮演战舰炮手,在不同的距离摧毁你的目。 新增 go 语言版,已编译,直接在“golang版”目录中运行,更加流畅。 golang版源代码在我的另一个项目“golang_test”中。
Copy Edit Raw Blame History
gunner.py 11.78 KB rocket049 authored 2018-04-18 15:38 . 改进gunner.py,变流畅了
#!/usr/bin/env python3
# 模拟炮舰主炮设计游戏
import pygame
from pygame.locals import *
from sys import exit
from threading import Thread,Lock,Timer
import time,math
from random import random
from lib.my_locale import msg
#273 上
#274 下
#275 左
#276 右
#32 空格
#27 ESC
class ship_gunner_app:
def __init__(self):
self.init_screen()
self.init_params()
def init_screen(self):
DEBUG=1 # 0、1 切换全屏、窗口模式
self.SCREEN_SIZE = (800, 600)
self.Fullscreen = True
if DEBUG==1:
self.screen = pygame.display.set_mode(self.SCREEN_SIZE, 0, 32)
self.Fullscreen = False
else:
self.screen = pygame.display.set_mode(self.SCREEN_SIZE, FULLSCREEN|DOUBLEBUF, 32)
def init_params(self):
self.LEFT_DOWN=False
self.RIGHT_DOWN=False
self.LOCK1 = Lock()
self.is_alive = True
self.background_image_filename = 'pics/bg2.png'
self.ship_image_filename = 'pics/ship1.png'
self.hole_img_filename = 'pics/hole1.png'
self.background = pygame.image.load(self.background_image_filename).convert()
self.ship1 = pygame.image.load(self.ship_image_filename).convert_alpha()
self.hole1 = pygame.image.load(self.hole_img_filename).convert_alpha()
self.font = pygame.font.Font("hei1.ttf", 18);
self.font_height = self.font.get_linesize()
pygame.event.set_blocked(None)
pygame.event.set_allowed( [MOUSEBUTTONUP,KEYDOWN,KEYUP,QUIT,USEREVENT] )
self.message = ''
self.x = 358
self.y = 273
self.target = [self.x+50,self.y+15]
self.gun_aim = (386,291)
self.hit_dist = (0,0)
self.hit_count = 0
self.hit_report = ''
self.damage = 0
smoke1_filename = 'pics/smoke1.png'
self.smoke1 = pygame.image.load(smoke1_filename).convert_alpha()
self.bs = pygame.mixer.Sound('sound/bomb.wav')
self.bs.set_volume(0.5)
def verify_hit(self,effect_hit_dist,effect_wucha):
hit_wucha = (effect_wucha[0]*(random()-0.5)*2,effect_wucha[1]*(random()-0.5)*2)
self.hit_dist = (self.gun_aim[0]-self.target[0]+hit_wucha[0],self.gun_aim[1]-self.target[1]+hit_wucha[1])
if self.hit_dist[0]*self.hit_dist[0] <= effect_hit_dist[0]*effect_hit_dist[0] and \
self.hit_dist[1]*self.hit_dist[1] <= effect_hit_dist[1]*effect_hit_dist[1]:
return True
else:
return False
def hit_object(self, smoke_point,x,y ):
self.LOCK1.acquire()
smoke_point.append( (x,y) )
self.damage += 50 - math.sqrt(x*x)
self.hit_count += 1
if self.damage<100:
self.hit_report=msg['hit']
else:
self.hit_report=msg['damage']
self.bs.play()
self.LOCK1.release()
def hit_missed(self):
self.LOCK1.acquire()
self.hit_report = msg['miss']
self.LOCK1.release()
def damage_ship(self,screen,x,y):
self.LOCK1.acquire()
screen.blit( self.font.render( msg['long_damage'] ,\
False, (255, 0, 0)).convert_alpha(), (320, 200) )
ship2 = pygame.image.load('pics/baozha1.png').convert_alpha()
screen.blit(ship2,(x,y))
screen.blit( self.font.render(msg['damage'], False, (255, 0, 0)).convert_alpha(), (10, self.font_height) )
pygame.display.flip()
self.bs.play()
time.sleep(1)
ship2 = pygame.image.load('pics/baozha2.png').convert_alpha()
screen.blit(ship2,(x,y))
pygame.display.flip()
time.sleep(1)
ship2 = pygame.image.load('pics/baozha3.png').convert_alpha()
screen.blit(ship2,(x,y))
pygame.display.flip()
self.LOCK1.release()
time.sleep(1)
def event_cicle(self,distance):
base_hit_dist = (45,12)
effect_hit_dist = (base_hit_dist[0]*2000.0/distance,base_hit_dist[1]*2000.0/distance)
base_wucha = (1.0,1.0)
effect_wucha = (base_wucha[0]*distance/2000.0,base_wucha[1]*distance/2000.0)
hit_time = distance/1000.0
bt_win = (330,568,40,30)
bt_quit = (390,568,40,30)
fire = pygame.mixer.Sound( file="sound/fire.wav" )
while self.is_alive:
event = pygame.event.wait()
d_time = time.time()-self.start_time
self.d_y = int(math.sin( math.pi*d_time/4.0)*30)
self.target = [self.x+50,self.y+self.d_y+self.dy+15]
self.LOCK1.acquire()
if event.type == QUIT:
self.is_alive = False
self.LOCK1.release()
break
elif event.type == KEYDOWN:
if event.key == 273:
self.dy += 1
self.target[1] += 1
elif event.key == 274:
self.dy -= 1
self.target[1] -=1
elif event.key == 275:
self.RIGHT_DOWN = True
elif event.key == 276:
self.LEFT_DOWN = True
elif event.key == 32:
if time.time()-self.load_timestamp>5:
fire.play()
if self.verify_hit(effect_hit_dist,effect_wucha):
timer1 = Timer(hit_time,self.hit_object,args=(self.smoke_point,self.hit_dist[0]*distance/2000.0,10 ))
timer1.start()
else:
timer2 = Timer(hit_time,self.hit_missed)
timer2.start()
self.fire_count += 1
self.load_timestamp = time.time()
elif event.key == 27:
self.is_alive = False
self.LOCK1.release()
break
elif event.type == KEYUP:
if event.key == 275:
self.RIGHT_DOWN = False
elif event.key == 276:
self.LEFT_DOWN = False
elif event.type == USEREVENT:
if event.message=='h':
self.x -= 1
if self.LEFT_DOWN:
self.x+=3
elif self.RIGHT_DOWN:
self.x-=2
elif event.type == MOUSEBUTTONUP:
if self.isOver(bt_win):
self.Fullscreen = not self.Fullscreen
if self.Fullscreen:
self.screen = pygame.display.set_mode(self.SCREEN_SIZE, FULLSCREEN|DOUBLEBUF, 32)
else:
self.screen = pygame.display.set_mode(self.SCREEN_SIZE, 0, 32)
if self.isOver(bt_quit):
self.is_alive = False
self.LOCK1.release()
break
self.LOCK1.release()
def shot_main( self,distance=4000 ):
clock1 = pygame.time.Clock()
self.init_params()
self.start_time = time.time()
self.dy=0 #垂直射角调整量
self.d_y=0
self.smoke_point = []
self.fire_count = 0
bt_win = (330,568,40,30)
bt_quit = (390,568,40,30)
self.load_timestamp = time.time()-6
mission_time = time.time()
t_event= Thread(target=self.event_cicle,args=(distance,))
t_event.start()
while self.is_alive:
self.LOCK1.acquire()
d_time = time.time()-self.start_time
self.d_y = int(math.sin( math.pi*d_time/4.0)*30)
self.target = [self.x+50,self.y+self.d_y+self.dy+15]
self.x -= 1
if self.LEFT_DOWN:
self.x+=3
elif self.RIGHT_DOWN:
self.x-=2
if time.time()-self.load_timestamp>5:
self.message = msg['ready_fire']
else:
self.message = msg['loading']
self.screen.fill((255, 255, 255))
self.screen.blit(self.background, (0,self.d_y+self.dy))
self.screen.blit(self.ship1,(self.x,self.y+self.d_y+self.dy))
self.screen.blit(self.hole1,(0,0))
for p in self.smoke_point:
self.show_smoke(self.screen,self.target[0]+p[0],self.target[1]+p[1])
pygame.draw.circle( self.screen,(255,0,0),self.gun_aim,2 )
self.screen.blit( self.font.render(msg['count_fire'].format(self.fire_count), False, (0, 255, 0)).convert_alpha(), (10, 0) )
self.screen.blit( self.font.render(msg['count_hit'].format(self.hit_count,self.damage), False, (0, 255, 0)).convert_alpha(), (200, 0) )
self.screen.blit( self.font.render( self.hit_report, False, (255, 0, 0)).convert_alpha(), (10, self.font_height) )
self.screen.blit( self.font.render( self.message, False, (255, 0, 0)).convert_alpha(), (300, self.font_height) )
self.screen.blit( self.font.render(msg['distance'] .format(distance),\
False, (0, 255, 0)).convert_alpha(), (600, 0) )
if self.Fullscreen:
win_mode = msg['win']
else:
win_mode = msg['fs']
self.draw_text_button(self.screen,bt_win,win_mode)
self.draw_text_button(self.screen,bt_quit,msg['quit'])
pygame.display.flip()
self.LOCK1.release()
if self.damage>=100:
self.is_alive = False
time.sleep(1)
self.damage_ship(self.screen,self.x,self.y+self.d_y+self.dy)
break
p_x = self.target[0]-self.gun_aim[0]
if p_x*p_x>40000 or time.time()-mission_time >600:
self.screen.blit( self.font.render( msg['fail'], False, (255, 0, 0)).convert_alpha(), (320, 200) )
pygame.display.flip()
time.sleep(2)
self.is_alive = False
break
clock1.tick(40)
def show_smoke(self,screen,x,y):
screen.blit(self.smoke1,(x-10,y-60))
def ask_todo(self,dist):
self.screen.fill((0,0,0))
self.screen.blit( self.font.render( msg['success'].format(dist),\
False, (255, 0, 0)).convert_alpha(), (270, 150) )
bt1 = (300,350,170,30)
bt2 = (300,200,170,30) #dist-1000
bt3 = (300,250,170,30) #dist
bt4 = (300,300,170,30) #dist+1000
self.draw_text_button(self.screen,bt1,msg['quit'])
self.draw_text_button(self.screen,bt2,msg['fire_dist'].format(dist-1000))
self.draw_text_button(self.screen,bt3,msg['fire_dist'].format(dist))
self.draw_text_button(self.screen,bt4,msg['fire_dist'].format(dist+1000))
pygame.display.flip()
ret = True
while True:
event = pygame.event.wait()
if event.type == MOUSEBUTTONUP:
if self.isOver(bt1):
ret = 0
break
elif self.isOver(bt2):
ret = dist-1000
break
elif self.isOver(bt3):
ret = dist
break
elif self.isOver(bt4):
ret = dist+1000
break
return ret
def draw_text_button(self,screen,rect=(10,10,10,10),text='b'):
pygame.draw.rect(screen,(0,255,0),rect,2)
screen.blit( self.font.render( text, False, (0, 255, 0)).convert_alpha(), (rect[0]+3, rect[1]+5) )
def isOver(self,rect=(0,0,1,1)):
point_x,point_y = pygame.mouse.get_pos()
in_x = rect[0] < point_x <rect[0]+rect[2]
in_y = rect[1] < point_y <rect[1]+rect[3]
return in_x and in_y
if __name__=='__main__':
dist=4000
pygame.init()
pygame.mixer.init()
app1 = ship_gunner_app()
while True:
app1.shot_main(dist)
dist = app1.ask_todo(dist)
if dist == 0:
break

Comment ( 0 )

You need to Sign in for post a comment

11_float_left_people 11_float_left_close