此示例爲簡單的實現遊戲服務器端和客戶端的消息同步,使用自定定義協議,引入了twisted網絡框架,還有諸多不足(其實就是半成品)。
python
資源下載地址:react
http://download.csdn.net/download/jailman/10194853
服務器
截圖網絡
服務器端:app
# coding=utf8 ''' Game server ''' import threading from random import randint as rint import pygame import queue from pygame.locals import * from twisted.internet import reactor from twisted.internet.protocol import Protocol, Factory ctrl_q = queue.Queue() enemy_q = queue.Queue() player_pos_q = queue.LifoQueue() ''' The game ''' class MySprite(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.master_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.direction = 0 self.velocity = Point(0.0, 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, height, columns): self.master_image = pygame.image.load(filename).convert_alpha() self.frame_width = width self.frame_height = height self.rect = Rect(0, 0, width, height) self.columns = columns # try to auto-calculate total frames rect = self.master_image.get_rect() self.last_frame = (rect.width // width) * (rect.height // height) - 1 def update(self, current_time, rate=30): # update animation frame number 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 # build current frame only if it changed if self.frame != self.old_frame: frame_x = (self.frame % self.columns) * self.frame_width frame_y = (self.frame // self.columns) * self.frame_height rect = Rect(frame_x, frame_y, self.frame_width, self.frame_height) self.image = self.master_image.subsurface(rect) self.old_frame = self.frame def __str__(self): return str(self.frame) + "," + str(self.first_frame) + \ "," + str(self.last_frame) + "," + str(self.frame_width) + \ "," + str(self.frame_height) + "," + str(self.columns) + \ "," + str(self.rect) # 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) + "}" def rungame(): pygame.init() playerHealth = 100 keys = [False, False, False, False] skybg = pygame.image.load("resources/images/skybg.png") missile = pygame.image.load("resources/images/bullet2.png") screen = pygame.display.set_mode((1024, 600)) pygame.display.set_caption("ChopperGun Server") timer = pygame.time.Clock() # warship sprite warship_group = pygame.sprite.Group() # enemy sprite chopper_group = pygame.sprite.Group() # player sprite player_group = pygame.sprite.Group() player = MySprite() player.load("resources/images/playerchopper.png", 173, 58, 4) player.position = 0, 350 player_group.add(player) # player missile sprite missile_group = pygame.sprite.Group() # enemy missile sprite enemy_missile_group = pygame.sprite.Group() # warship missile group warship_missile_group = pygame.sprite.Group() # flame sprite flame_group = pygame.sprite.Group() def addNewFlame(position): flame = MySprite() flame.load("resources/images/flame.png", 64, 64, 4) flame.position = position flame_group.add(flame) # warship flame warship_flame_group = pygame.sprite.Group() def addNewWarshipFlame(position): warship_flame = MySprite() warship_flame.load("resources/images/warship_flame.png", 64, 64, 4) warship_flame.position = position warship_flame_group.add(warship_flame) badtimer = 100 badtimer1 = 0 missile_launched = 0 missile_hit = 0 missile_hit_warship = 0 total_enemy_showedup = 0 enemy_missile_launched = 0 warship_health = 10 # to make autopilot missile launch interval tickstart = [] tickstart.append(pygame.time.get_ticks()) # player move speed player_move_speed = 5 while True: # start game ticks timer.tick(60) ticks = pygame.time.get_ticks() screen.fill(0) # draw background sky screen.blit(skybg, (0, 0)) # add warship sprite (only one warship on the screen) if len(warship_group) == 0: warship = MySprite() warship.load("resources/images/warship.png", 350, 70, 1) warship.position = 1024, 500 warship_group.add(warship) # adjust warship to come close to player if warship.X < player.X + 200: warship.X += 1 elif warship.X > player.X + 200: warship.X -= 1 # draw warship warship_group.update(ticks) warship_group.draw(screen) # warship launch missile for warship in warship_group: if len(warship_missile_group) == 0: if warship.X < 800: warship_missile = MySprite() warship_missile.load( "resources/images/warship_missile.png", 32, 121, 1) warship_missile.position = warship.X + 160, warship.Y - 60 warship_missile_group.add(warship_missile) # guide missile & change missile position for warship_missilex in warship_missile_group: warship_missilex.Y -= 1 if warship_missilex.Y < -121: warship_missile_group.remove(warship_missilex) # warship missile & enemy collision detect collision = None collision = pygame.sprite.spritecollideany( warship_missilex, chopper_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(warship_missilex, collision): chopper_group.remove(collision) flameposition = warship_missilex.position addNewFlame(flameposition) # warship missile & enemy missile collision detect collision = None collision = pygame.sprite.spritecollideany( warship_missilex, enemy_missile_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(warship_missilex, collision): enemy_missile_group.remove(collision) flameposition = warship_missilex.position addNewFlame(flameposition) # warship missile & player missile collision detect collision = None collision = pygame.sprite.spritecollideany( warship_missilex, missile_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(warship_missilex, collision): missile_group.remove(collision) flameposition = warship_missilex.position addNewFlame(flameposition) # warship missile & player collision detect collision = None collision = pygame.sprite.spritecollideany( warship_missilex, player_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(warship_missilex, collision): playerHealth -= 10 warship_missile_group.remove(warship_missilex) flameposition = warship_missilex.position addNewFlame(flameposition) # add random enenmy chopper badtimer -= 1 if badtimer == 0: chopper = MySprite() chopper.load("resources/images/enemychopper.png", 173, 60, 4) chopper.position = 1024, rint(0, 400) # add enemy position to queue enemy_q.put(str([chopper.X, chopper.Y])) chopper_group.add(chopper) total_enemy_showedup += 1 badtimer = 150 - (badtimer1 * 2) if badtimer1 >= 35: badtimer1 = 35 else: badtimer1 += 5 # change enemy chopper position for chopper in chopper_group: chopper.X -= 2 if chopper.X < -173: chopper_group.remove(chopper) # enemy chopper launch missile if chopper.X % 500 == 0: enemy_missile_launched += 1 enemy_missile = MySprite() enemy_missile.load("resources/images/missile.png", 64, 16, 1) enemy_missile.position = chopper.X, chopper.Y + 25 enemy_missile_group.add(enemy_missile) # change enemy missile position for enemy_missilex in enemy_missile_group: enemy_missilex.X -= 4 if enemy_missilex.X < -64: enemy_missile_group.remove(enemy_missilex) # enemy missile & player collision detect collision = None collision = pygame.sprite.spritecollideany( enemy_missilex, player_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(enemy_missilex, collision): enemy_missile_group.remove(enemy_missilex) playerHealth -= 1 flameposition = player.X + 70, player.Y addNewFlame(flameposition) # enemy missile & player missile collision detect (to remove enemy/player missile & add flame) collision = None collision = pygame.sprite.spritecollideany( enemy_missilex, missile_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(enemy_missilex, collision): missile_group.remove(collision) enemy_missile_group.remove(enemy_missilex) flameposition = enemy_missilex.X, enemy_missilex.Y - 30 addNewFlame(flameposition) # draw enemy chopper spritew chopper_group.update(ticks) chopper_group.draw(screen) # draw player player_group.update(ticks) player_group.draw(screen) # change player missile position for missilex in missile_group: missilex.velocity.x += 0.5 missilex.X += missilex.velocity.x if missilex.X > 1056: missile_group.remove(missilex) # player missile & enemy chopper collision detect collision = None collision = pygame.sprite.spritecollideany(missilex, chopper_group) if collision != None: if pygame.sprite.collide_circle_ratio(1)(missilex, collision): missile_hit += 1 chopper_group.remove(collision) missile_group.remove(missilex) flameposition = missilex.X + \ 80, missilex.Y - 30 addNewFlame(flameposition) # player missile & enemy warship collision detect collision = None collision = pygame.sprite.spritecollideany(missilex, warship_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(missilex, collision): missile_hit_warship += 1 warship_health -= 1 missile_group.remove(missilex) warshipflameposition = missilex.X + \ rint(1, 100), missilex.Y - 20 addNewWarshipFlame(warshipflameposition) # random flame after warship is destroyed if warship_health == 0: for i in xrange(20): position = warship.X + \ rint(-10, 300), warship.Y + \ rint(-20, 100) addNewFlame(position) warship_health = 10 warship_group.remove(collision) # enemy collision with player collision = None collision = pygame.sprite.spritecollideany(player, chopper_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(player, collision): chopper_group.remove(collision) playerHealth -= 1 flameposition = player.X + 70, player.Y addNewFlame(flameposition) # draw player missiles missile_group.update(ticks) missile_group.draw(screen) # draw enemy missiles enemy_missile_group.update(ticks) enemy_missile_group.draw(screen) # draw warship missile warship_missile_group.update(ticks) warship_missile_group.draw(screen) # draw flame for x in flame_group: if x.frame == x.last_frame: flame_group.remove(x) flame_group.update(ticks) flame_group.draw(screen) # draw warship flame for x in warship_flame_group: if x.frame == x.last_frame: warship_flame_group.remove(x) warship_flame_group.update(ticks) warship_flame_group.draw(screen) # game statistics font = pygame.font.SysFont(None, 25) text1 = font.render("Player Health: " + str(playerHealth), True, (255, 0, 0)) screen.blit(text1, (0, 480)) text2 = font.render("Missile Launched: " + str(missile_launched), True, (255, 0, 0)) screen.blit(text2, (0, 500)) text3 = font.render("Missile Hit: " + str(missile_hit), True, (255, 0, 0)) screen.blit(text3, (0, 520)) if not missile_launched == 0: hitrate = float(missile_hit) / float(missile_launched) * 100 text4 = font.render("Hit Rate: " + str(hitrate) + "%", True, (255, 0, 0)) else: text4 = font.render("Hit Rate: " + "0%", True, (255, 0, 0)) screen.blit(text4, (0, 540)) text5 = font.render("Total Enemies: " + str(total_enemy_showedup), True, (255, 0, 0)) screen.blit(text5, (0, 560)) text6 = font.render("Enemy Missile Launched: " + str(enemy_missile_launched), True, (255, 0, 0)) screen.blit(text6, (0, 580)) pygame.display.update() key = pygame.key.get_pressed() if key[pygame.K_ESCAPE]: exit() for event in pygame.event.get(): # if event.type == pygame.KEYDOWN: # if event.key == K_w: # keys[0] = True # elif event.key == K_a: # keys[1] = True # elif event.key == K_s: # keys[2] = True # elif event.key == K_d: # keys[3] = True # if event.type == pygame.KEYUP: # if event.key == pygame.K_w: # keys[0] = False # elif event.key == pygame.K_a: # keys[1] = False # elif event.key == pygame.K_s: # keys[2] = False # elif event.key == pygame.K_d: # keys[3] = False # # add missile sprite # if event.type == pygame.MOUSEBUTTONDOWN: # pressed_array = pygame.mouse.get_pressed() # for index in range(len(pressed_array)): # if pressed_array[index]: # if index == 0: # missile_launched += 1 # missile = MySprite() # missile.load("resources/images/bullet2.png", 32, 16, 1) # missile.position = player.X + \ # 120, player.Y + 35 # missile_group.add(missile) if event.type == pygame.QUIT: pygame.quit() exit() # move player sprite if keys[0]: if not player.Y < 0: player.Y -= player_move_speed elif keys[1]: if not player.X < 0: player.X -= player_move_speed if keys[2]: if not player.Y > 500: player.Y += player_move_speed elif keys[3]: if not player.X > 1024: player.X += player_move_speed # print player.position ''' Auto pilot The codes below will drive the player chopper automaticly The player vs enemy loss ratio is around 10:1 ''' # if not len(chopper_group) == 0: # enemy = chopper_group.sprites()[0] # posdiffy = enemy.Y - player.Y # # print posdiffy # if posdiffy < -10: # for em in enemy_missile_group: # if abs(em.X - player.X) < 100 and -100 < (em.Y - player.Y) < 0: # keys[0] = False # keys[2] = False # break # else: # keys[0] = True # keys[2] = False # elif posdiffy > 10: # for em in enemy_missile_group: # if abs(em.X - player.X) < 100 and 0 < (em.Y - player.Y) < 100: # keys[0] = False # keys[2] = False # break # else: # keys[0] = False # keys[2] = True # elif -10 <= posdiffy <= 10: # keys[0] = False # keys[2] = False # missile_launched += 1 # if len(missile_group) < 2: # if ticks - tickstart[0] > 200: # tickstart.pop(0) # tickstart.append(ticks) # missile = MySprite() # missile.load("resources/images/bullet2.png", 32, 16, 1) # missile.position = player.X + \ # 120, player.Y + 35 # missile_group.add(missile) ''' Remote pilot The codes below will receive control orders from remote server ''' if not ctrl_q.empty(): ctrl = ctrl_q.get() if ctrl == "w": keys[0] = True if ctrl == "a": keys[1] = True if ctrl == "s": keys[2] = True if ctrl == "d": keys[3] = True if ctrl == "wq": keys[0] = False if ctrl == "aq": keys[1] = False if ctrl == "sq": keys[2] = False if ctrl == "dq": keys[3] = False if ctrl == "j": missile = MySprite() missile.load("resources/images/bullet2.png", 32, 16, 1) missile.position = player.X + \ 120, player.Y + 35 missile_group.add(missile) if not player_pos_q.empty(): pos = eval(player_pos_q.get()) player.X = pos[0] player.Y = pos[1] # run game in thread class Server_Thread(threading.Thread): def __init__(self): super(Server_Thread, self).__init__() def run(self): rungame() # twisted socket communication class TSServProtocol(Protocol): def connectionMade(self): clnt = self.clnt = self.transport.getPeer().host print '...connected from :', clnt # start server game thread when client connects st = Server_Thread() st.start() def dataReceived(self, data): # message = "Server roger!" # self.transport.write('[%s] %s' % (ctime(), message)) send_message = {"alive": "ok"} try: send_message["enemypos"] = enemy_q.get(False) except: pass self.transport.write(str(send_message)) if data: print "Received from client: " + data try: ctrl = eval(data)["ctrl"] ctrl_q.put(ctrl) pos = eval(data)["pos"] player_pos_q.put(pos) except: pass def run_socketserver(Port): factory = Factory() factory.protocol = TSServProtocol print 'waiting for connection...' reactor.listenTCP(Port, factory) reactor.run() Port = 9999 run_socketserver(Port)
# coding=utf8 ''' Game client ''' import threading import time from random import randint as rint import pygame import queue from pygame.locals import * from twisted.internet import reactor from twisted.internet.protocol import Protocol, ClientFactory ctrl_q = queue.Queue() pos_q = queue.LifoQueue() enemy_q = queue.Queue() ''' The game ''' class MySprite(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.master_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.direction = 0 self.velocity = Point(0.0, 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, height, columns): self.master_image = pygame.image.load(filename).convert_alpha() self.frame_width = width self.frame_height = height self.rect = Rect(0, 0, width, height) self.columns = columns # try to auto-calculate total frames rect = self.master_image.get_rect() self.last_frame = (rect.width // width) * (rect.height // height) - 1 def update(self, current_time, rate=30): # update animation frame number 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 # build current frame only if it changed if self.frame != self.old_frame: frame_x = (self.frame % self.columns) * self.frame_width frame_y = (self.frame // self.columns) * self.frame_height rect = Rect(frame_x, frame_y, self.frame_width, self.frame_height) self.image = self.master_image.subsurface(rect) self.old_frame = self.frame def __str__(self): return str(self.frame) + "," + str(self.first_frame) + \ "," + str(self.last_frame) + "," + str(self.frame_width) + \ "," + str(self.frame_height) + "," + str(self.columns) + \ "," + str(self.rect) # 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) + "}" def rungame(): pygame.init() playerHealth = 100 keys = [False, False, False, False] skybg = pygame.image.load("resources/images/skybg.png") missile = pygame.image.load("resources/images/bullet2.png") screen = pygame.display.set_mode((1024, 600)) pygame.display.set_caption("ChopperGun Client") timer = pygame.time.Clock() # warship sprite warship_group = pygame.sprite.Group() # enemy sprite chopper_group = pygame.sprite.Group() # player sprite player_group = pygame.sprite.Group() player = MySprite() player.load("resources/images/playerchopper.png", 173, 58, 4) player.position = 0, 350 player_group.add(player) # player missile sprite missile_group = pygame.sprite.Group() # enemy missile sprite enemy_missile_group = pygame.sprite.Group() # warship missile group warship_missile_group = pygame.sprite.Group() # flame sprite flame_group = pygame.sprite.Group() def addNewFlame(position): flame = MySprite() flame.load("resources/images/flame.png", 64, 64, 4) flame.position = position flame_group.add(flame) # warship flame warship_flame_group = pygame.sprite.Group() def addNewWarshipFlame(position): warship_flame = MySprite() warship_flame.load("resources/images/warship_flame.png", 64, 64, 4) warship_flame.position = position warship_flame_group.add(warship_flame) missile_launched = 0 missile_hit = 0 missile_hit_warship = 0 total_enemy_showedup = 0 enemy_missile_launched = 0 warship_health = 10 # to make autopilot missile launch interval tickstart = [] tickstart.append(pygame.time.get_ticks()) # to calc time timestart = [] timestart.append(int(time.time())) # player move speed player_move_speed = 5 while True: # start game ticks timer.tick(60) ticks = pygame.time.get_ticks() screen.fill(0) # draw background sky screen.blit(skybg, (0, 0)) # add warship sprite (only one warship on the screen) if len(warship_group) == 0: warship = MySprite() warship.load("resources/images/warship.png", 350, 70, 1) warship.position = 1024, 500 warship_group.add(warship) # adjust warship to come close to player if warship.X < player.X + 200: warship.X += 1 elif warship.X > player.X + 200: warship.X -= 1 # draw warship warship_group.update(ticks) warship_group.draw(screen) # warship launch missile for warship in warship_group: if len(warship_missile_group) == 0: if warship.X < 800: warship_missile = MySprite() warship_missile.load( "resources/images/warship_missile.png", 32, 121, 1) warship_missile.position = warship.X + 160, warship.Y - 60 warship_missile_group.add(warship_missile) # guide missile & change missile position for warship_missilex in warship_missile_group: warship_missilex.Y -= 1 if warship_missilex.Y < -121: warship_missile_group.remove(warship_missilex) # warship missile & enemy collision detect collision = None collision = pygame.sprite.spritecollideany( warship_missilex, chopper_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(warship_missilex, collision): chopper_group.remove(collision) flameposition = warship_missilex.position addNewFlame(flameposition) # warship missile & enemy missile collision detect collision = None collision = pygame.sprite.spritecollideany( warship_missilex, enemy_missile_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(warship_missilex, collision): enemy_missile_group.remove(collision) flameposition = warship_missilex.position addNewFlame(flameposition) # warship missile & player missile collision detect collision = None collision = pygame.sprite.spritecollideany( warship_missilex, missile_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(warship_missilex, collision): missile_group.remove(collision) flameposition = warship_missilex.position addNewFlame(flameposition) # warship missile & player collision detect collision = None collision = pygame.sprite.spritecollideany( warship_missilex, player_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(warship_missilex, collision): playerHealth -= 10 warship_missile_group.remove(warship_missilex) flameposition = warship_missilex.position addNewFlame(flameposition) # add random enenmy chopper chopper = MySprite() chopper.load("resources/images/enemychopper.png", 173, 60, 4) # chopper.position = 1024, rint(0, 400) # add enemy from server try: enemy_pos = eval(enemy_q.get(False)) chopper.position = enemy_pos[0], enemy_pos[1] chopper_group.add(chopper) total_enemy_showedup += 1 except: pass # change enemy chopper position for chopper in chopper_group: chopper.X -= 2 if chopper.X < -173: chopper_group.remove(chopper) # enemy chopper launch missile if chopper.X % 500 == 0: enemy_missile_launched += 1 enemy_missile = MySprite() enemy_missile.load("resources/images/missile.png", 64, 16, 1) enemy_missile.position = chopper.X, chopper.Y + 25 enemy_missile_group.add(enemy_missile) # change enemy missile position for enemy_missilex in enemy_missile_group: enemy_missilex.X -= 4 if enemy_missilex.X < -64: enemy_missile_group.remove(enemy_missilex) # enemy missile & player collision detect collision = None collision = pygame.sprite.spritecollideany( enemy_missilex, player_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(enemy_missilex, collision): enemy_missile_group.remove(enemy_missilex) playerHealth -= 1 flameposition = player.X + 70, player.Y addNewFlame(flameposition) # enemy missile & player missile collision detect (to remove enemy/player missile & add flame) collision = None collision = pygame.sprite.spritecollideany( enemy_missilex, missile_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(enemy_missilex, collision): missile_group.remove(collision) enemy_missile_group.remove(enemy_missilex) flameposition = enemy_missilex.X, enemy_missilex.Y - 30 addNewFlame(flameposition) # draw enemy chopper spritew chopper_group.update(ticks) chopper_group.draw(screen) # draw player player_group.update(ticks) player_group.draw(screen) # change player missile position for missilex in missile_group: missilex.velocity.x += 0.5 missilex.X += missilex.velocity.x if missilex.X > 1056: missile_group.remove(missilex) # player missile & enemy chopper collision detect collision = None collision = pygame.sprite.spritecollideany(missilex, chopper_group) if collision != None: if pygame.sprite.collide_circle_ratio(1)(missilex, collision): missile_hit += 1 chopper_group.remove(collision) missile_group.remove(missilex) flameposition = missilex.X + \ 80, missilex.Y - 30 addNewFlame(flameposition) # player missile & enemy warship collision detect collision = None collision = pygame.sprite.spritecollideany(missilex, warship_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(missilex, collision): missile_hit_warship += 1 warship_health -= 1 missile_group.remove(missilex) warshipflameposition = missilex.X + \ rint(1, 100), missilex.Y - 20 addNewWarshipFlame(warshipflameposition) # random flame after warship is destroyed if warship_health == 0: for i in xrange(20): position = warship.X + \ rint(-10, 300), warship.Y + \ rint(-20, 100) addNewFlame(position) warship_health = 10 warship_group.remove(collision) # enemy collision with player collision = None collision = pygame.sprite.spritecollideany(player, chopper_group) if collision != None: if pygame.sprite.collide_circle_ratio(0.65)(player, collision): chopper_group.remove(collision) playerHealth -= 1 flameposition = player.X + 70, player.Y addNewFlame(flameposition) # draw player missiles missile_group.update(ticks) missile_group.draw(screen) # draw enemy missiles enemy_missile_group.update(ticks) enemy_missile_group.draw(screen) # draw warship missile warship_missile_group.update(ticks) warship_missile_group.draw(screen) # draw flame for x in flame_group: if x.frame == x.last_frame: flame_group.remove(x) flame_group.update(ticks) flame_group.draw(screen) # draw warship flame for x in warship_flame_group: if x.frame == x.last_frame: warship_flame_group.remove(x) warship_flame_group.update(ticks) warship_flame_group.draw(screen) # game statistics font = pygame.font.SysFont(None, 25) text1 = font.render("Player Health: " + str(playerHealth), True, (255, 0, 0)) screen.blit(text1, (0, 480)) text2 = font.render("Missile Launched: " + str(missile_launched), True, (255, 0, 0)) screen.blit(text2, (0, 500)) text3 = font.render("Missile Hit: " + str(missile_hit), True, (255, 0, 0)) screen.blit(text3, (0, 520)) if not missile_launched == 0: hitrate = float(missile_hit) / float(missile_launched) * 100 text4 = font.render("Hit Rate: " + str(hitrate) + "%", True, (255, 0, 0)) else: text4 = font.render("Hit Rate: " + "0%", True, (255, 0, 0)) screen.blit(text4, (0, 540)) text5 = font.render("Total Enemies: " + str(total_enemy_showedup), True, (255, 0, 0)) screen.blit(text5, (0, 560)) text6 = font.render("Enemy Missile Launched: " + str(enemy_missile_launched), True, (255, 0, 0)) screen.blit(text6, (0, 580)) pygame.display.update() ''' Local human pilot The codes below will drive the player chopper with local control ''' # key = pygame.key.get_pressed() # if key[pygame.K_ESCAPE]: # exit() # for event in pygame.event.get(): # if event.type == pygame.KEYDOWN: # if event.key == K_w: # keys[0] = True # elif event.key == K_a: # keys[1] = True # elif event.key == K_s: # keys[2] = True # elif event.key == K_d: # keys[3] = True # if event.type == pygame.KEYUP: # if event.key == pygame.K_w: # keys[0] = False # elif event.key == pygame.K_a: # keys[1] = False # elif event.key == pygame.K_s: # keys[2] = False # elif event.key == pygame.K_d: # keys[3] = False # # add missile sprite # if event.type == pygame.MOUSEBUTTONDOWN: # pressed_array = pygame.mouse.get_pressed() # for index in range(len(pressed_array)): # if pressed_array[index]: # if index == 0: # missile_launched += 1 # missile = MySprite() # missile.load("resources/images/bullet2.png", 32, 16, 1) # missile.position = player.X + \ # 120, player.Y + 35 # missile_group.add(missile) # if event.type == pygame.QUIT: # pygame.quit() # exit() # move player sprite if keys[0]: if not player.Y < 0: player.Y -= player_move_speed elif keys[1]: if not player.X < 0: player.X -= player_move_speed if keys[2]: if not player.Y > 500: player.Y += player_move_speed elif keys[3]: if not player.X > 1024: player.X += player_move_speed # print player.position ''' Auto pilot The codes below will drive the player chopper automaticly The player vs enemy loss ratio is around 10:1 ''' # if not len(chopper_group) == 0: # enemy = chopper_group.sprites()[0] # posdiffy = enemy.Y - player.Y # # print posdiffy # if posdiffy < -10: # for em in enemy_missile_group: # if abs(em.X - player.X) < 100 and -100 < (em.Y - player.Y) < 0: # keys[0] = False # keys[2] = False # break # else: # keys[0] = True # keys[2] = False # elif posdiffy > 10: # for em in enemy_missile_group: # if abs(em.X - player.X) < 100 and 0 < (em.Y - player.Y) < 100: # keys[0] = False # keys[2] = False # break # else: # keys[0] = False # keys[2] = True # elif -10 <= posdiffy <= 10: # keys[0] = False # keys[2] = False # missile_launched += 1 # if len(missile_group) < 2: # if ticks - tickstart[0] > 200: # tickstart.pop(0) # tickstart.append(ticks) # missile = MySprite() # missile.load("resources/images/bullet2.png", 32, 16, 1) # missile.position = player.X + \ # 120, player.Y + 35 # missile_group.add(missile) ''' Remote pilot The codes below will send control orders to remote server ''' key = pygame.key.get_pressed() if key[pygame.K_ESCAPE]: exit() for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == K_w: keys[0] = True ctrl_q.put("w") elif event.key == K_a: keys[1] = True ctrl_q.put("a") elif event.key == K_s: keys[2] = True ctrl_q.put("s") elif event.key == K_d: keys[3] = True ctrl_q.put("d") if event.type == pygame.KEYUP: if event.key == pygame.K_w: keys[0] = False ctrl_q.put("wq") elif event.key == pygame.K_a: keys[1] = False ctrl_q.put("aq") elif event.key == pygame.K_s: keys[2] = False ctrl_q.put("sq") elif event.key == pygame.K_d: keys[3] = False ctrl_q.put("dq") if event.type == pygame.QUIT: pygame.quit() exit() # add missile sprite if event.type == pygame.MOUSEBUTTONDOWN: pressed_array = pygame.mouse.get_pressed() for index in range(len(pressed_array)): if pressed_array[index]: if index == 0: ctrl_q.put("j") missile_launched += 1 missile = MySprite() missile.load("resources/images/bullet2.png", 32, 16, 1) missile.position = player.X + \ 120, player.Y + 35 missile_group.add(missile) # player position # timenow = time.time() # if timenow - timestart[0] > 1: # timestart.pop() # timestart.append(timenow) # print "ingame:" + str(player.position) pos_q.put(str([player.X, player.Y])) # run game in thread class Client_Thread(threading.Thread): def __init__(self): super(Client_Thread, self).__init__() def run(self): rungame() ct = Client_Thread() ct.start() # twisted socket communication class TSClntProtocol(Protocol): def sendData(self): send_message = {"alive": "ok"} try: ctrl = ctrl_q.get(False) send_message["ctrl"] = ctrl pos = pos_q.get(False) send_message["pos"] = pos except: pass # print send_message self.transport.write(str(send_message)) def connectionMade(self): self.sendData() def dataReceived(self, data): if data: print data try: enemypos = eval(data)["enemypos"] enemy_q.put(enemypos) except: pass self.sendData() else: self.transport.loseConnection() class TSClntFactory(ClientFactory): protocol = TSClntProtocol clientConnectionLost = clientConnectionFailed = \ lambda self, connector, reason: reactor.stop() def run_socketclient(Host, Port): reactor.connectTCP(Host, Port, TSClntFactory()) reactor.run() Host = "127.0.0.1" Port = 9999 run_socketclient(Host, Port)