def setup(self): MenuView.setup(self) width, height = self.controller.window.width, self.controller.window.height self.layout = VerticalLayout(0, 0) self.text_input = TextWidget(self.controller.window, G.IP_ADDRESS, 0, 0, width=160, height=20, font_name='Arial', batch=self.batch) self.controller.window.push_handlers(self.text_input) self.text_input.focus() def text_input_callback(symbol, modifier): G.IP_ADDRESS = self.text_input.text self.text_input.push_handlers(key_released=text_input_callback) button = self.Button(caption=G._("Connect to server"), on_click=self.controller.start_multiplayer_game) self.layout.add(button) self.buttons.append(button) button= self.Button(caption=G._("Launch server"), on_click=self.launch_server) self.layout.add(button) self.buttons.append(button) button= self.Button(caption=G._("Done"), on_click=self.controller.main_menu) self.layout.add(button) self.buttons.append(button) self.label = Label('Play Multiplayer', font_name='ChunkFive Roman', font_size=25, x=width/2, y=self.frame.y + self.frame.height, anchor_x='center', anchor_y='top', color=(255, 255, 255, 255), batch=self.batch, group=self.labels_group) self.on_resize(width, height)
def setup(self): MenuView.setup(self) width, height = self.controller.window.width, self.controller.window.height self.layout = VerticalLayout(0, 0) textures_enabled = len(G.texture_pack_list.available_texture_packs) > 1 self.text_input = TextWidget(self.controller.window, G.USERNAME, 0, 0, width=160, height=20, font_name='Arial', batch=self.batch) self.controller.window.push_handlers(self.text_input) self.text_input.focus() self.text_input.caret.mark = len(self.text_input.document.text) # Don't select the whole text def text_input_callback(symbol, modifier): G.USERNAME = self.text_input.text self.text_input.push_handlers(key_released=text_input_callback) hl = HorizontalLayout(0, 0) sb = self.Scrollbar(x=0, y=0, width=300, height=40, sb_width=20, sb_height=40, caption="Music") hl.add(sb) def change_sound_volume(pos): print(G.EFFECT_VOLUME) G.EFFECT_VOLUME = float(float(pos) / 100) sb = self.Scrollbar(x=0, y=0, width=300, height=40, sb_width=20, sb_height=40, caption="Sound", pos=int(G.EFFECT_VOLUME * 100), on_pos_change=change_sound_volume) hl.add(sb) self.layout.add(hl) hl = HorizontalLayout(0, 0) button = self.Button(width=300, caption=G._("Controls..."), on_click=self.controller.controls) hl.add(button) self.buttons.append(button) button = self.Button(width=300, caption=G._("Textures"), on_click=self.controller.textures, enabled=textures_enabled) hl.add(button) self.buttons.append(button) self.layout.add(hl) button = self.Button(width=610, caption=G._("Done"), on_click=self.controller.main_menu) self.layout.add(button) self.buttons.append(button) self.label = Label('Options', font_name='ChunkFive Roman', font_size=25, x=width/2, y=self.frame.y + self.frame.height, anchor_x='center', anchor_y='top', color=(255, 255, 255, 255), batch=self.batch, group=self.labels_group) self.on_resize(width, height)
class MainMenuView(MenuView): def setup(self): MenuView.setup(self) width, height = self.controller.window.width, self.controller.window.height self.text_input = TextWidget(self.controller.window, G.IP_ADDRESS, 0, 0, width=160, height=20, font_name='Arial', batch=self.batch) self.controller.window.push_handlers(self.text_input) self.text_input.focus() def text_input_callback(symbol, modifier): G.IP_ADDRESS = self.text_input.text self.text_input.push_handlers(key_released=text_input_callback) self.buttons.append(self.Button(caption="Connect to Server",on_click=self.controller.start_game)) self.buttons.append(self.Button(caption="Launch Server",on_click=self.launch_server)) self.buttons.append(self.Button(caption="Options...",on_click=self.controller.game_options)) self.buttons.append(self.Button(caption="Exit game",on_click=self.controller.exit_game)) self.label = Label(G.APP_NAME, font_name='ChunkFive Roman', font_size=50, x=width/2, y=self.frame.y + self.frame.height, anchor_x='center', anchor_y='top', color=(255, 255, 255, 255), batch=self.batch, group=self.labels_group) self.on_resize(width, height) def launch_server(self): subprocess.Popen([sys.executable, "server.py"], creationflags=subprocess.CREATE_NEW_CONSOLE) localip = [ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][0] self.text_input.text = localip G.IP_ADDRESS = localip def on_resize(self, width, height): MenuView.on_resize(self, width, height) self.label.y = self.frame.y + self.frame.height - 15 self.label.x = width / 2 self.text_input.resize(x=self.frame.x + (self.frame.width - self.text_input.width) / 2 + 5, y=self.frame.y + (self.frame.height) / 2 + 75, width=150)
def setup(self): MenuView.setup(self) width, height = self.controller.window.width, self.controller.window.height self.layout = VerticalLayout(0, 0) textures_enabled = len(G.texture_pack_list.available_texture_packs) > 1 self.text_input = TextWidget(self.controller.window, G.USERNAME, 0, 0, width=160, height=20, font_name='Arial', batch=self.batch) self.controller.window.push_handlers(self.text_input) self.text_input.focus() self.text_input.caret.mark = len(self.text_input.document.text) # Don't select the whole text def text_input_callback(symbol, modifier): G.USERNAME = self.text_input.text self.text_input.push_handlers(key_released=text_input_callback) hl = HorizontalLayout(0, 0) sb = self.Scrollbar(x=0, y=0, width=300, height=40, sb_width=20, sb_height=40, caption="Music") hl.add(sb) def change_sound_volume(pos): print G.EFFECT_VOLUME G.EFFECT_VOLUME = float(float(pos) / 100) sb = self.Scrollbar(x=0, y=0, width=300, height=40, sb_width=20, sb_height=40, caption="Sound", pos=int(G.EFFECT_VOLUME * 100), on_pos_change=change_sound_volume) hl.add(sb) self.layout.add(hl) hl = HorizontalLayout(0, 0) button = self.Button(width=300, caption=G._("Controls..."), on_click=self.controller.controls) hl.add(button) self.buttons.append(button) button = self.Button(width=300, caption=G._("Textures"), on_click=self.controller.textures, enabled=textures_enabled) hl.add(button) self.buttons.append(button) self.layout.add(hl) button = self.Button(width=610, caption=G._("Done"), on_click=self.controller.main_menu) self.layout.add(button) self.buttons.append(button) self.label = Label('Options', font_name='ChunkFive Roman', font_size=25, x=width/2, y=self.frame.y + self.frame.height, anchor_x='center', anchor_y='top', color=(255, 255, 255, 255), batch=self.batch, group=self.labels_group) self.on_resize(width, height)
def setup(self): MenuView.setup(self) width, height = self.controller.window.width, self.controller.window.height texturepacks_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', 'texturepacks') self.text_input = TextWidget(self.controller.window, G.USERNAME, 0, 0, width=160, height=20, font_name='Arial', batch=self.batch) self.controller.window.push_handlers(self.text_input) self.text_input.focus() self.text_input.caret.mark = len(self.text_input.document.text) # Don't select the whole text def text_input_callback(symbol, modifier): G.USERNAME = self.text_input.text self.text_input.push_handlers(key_released=text_input_callback) self.buttons.append(self.Button(caption="Controls...", on_click=self.controller.controls)) self.buttons.append(self.Button(caption="Textures", on_click=self.controller.textures, enabled=os.path.exists(texturepacks_dir))) self.buttons.append(self.Button(caption="Done", on_click=self.controller.main_menu)) self.on_resize(width, height)
def setup(self): MenuView.setup(self) width, height = self.controller.window.width, self.controller.window.height self.text_input = TextWidget(self.controller.window, G.IP_ADDRESS, 0, 0, width=160, height=20, font_name='Arial', batch=self.batch) self.controller.window.push_handlers(self.text_input) self.text_input.focus() def text_input_callback(symbol, modifier): G.IP_ADDRESS = self.text_input.text self.text_input.push_handlers(key_released=text_input_callback) self.buttons.append(self.Button(caption="Connect to Server",on_click=self.controller.start_game)) self.buttons.append(self.Button(caption="Launch Server",on_click=self.launch_server)) self.buttons.append(self.Button(caption="Options...",on_click=self.controller.game_options)) self.buttons.append(self.Button(caption="Exit game",on_click=self.controller.exit_game)) self.label = Label(G.APP_NAME, font_name='ChunkFive Roman', font_size=50, x=width/2, y=self.frame.y + self.frame.height, anchor_x='center', anchor_y='top', color=(255, 255, 255, 255), batch=self.batch, group=self.labels_group) self.on_resize(width, height)
class MultiplayerView(MenuView): def setup(self): MenuView.setup(self) width, height = self.controller.window.width, self.controller.window.height self.layout = VerticalLayout(0, 0) self.text_input = TextWidget(self.controller.window, G.IP_ADDRESS, 0, 0, width=160, height=20, font_name='Arial', batch=self.batch) self.controller.window.push_handlers(self.text_input) self.text_input.focus() def text_input_callback(symbol, modifier): G.IP_ADDRESS = self.text_input.text self.text_input.push_handlers(key_released=text_input_callback) button = self.Button(caption=G._("Connect to server"), on_click=self.controller.start_multiplayer_game) self.layout.add(button) self.buttons.append(button) button= self.Button(caption=G._("Launch server"), on_click=self.launch_server) self.layout.add(button) self.buttons.append(button) button= self.Button(caption=G._("Done"), on_click=self.controller.main_menu) self.layout.add(button) self.buttons.append(button) self.label = Label('Play Multiplayer', font_name='ChunkFive Roman', font_size=25, x=width/2, y=self.frame.y + self.frame.height, anchor_x='center', anchor_y='top', color=(255, 255, 255, 255), batch=self.batch, group=self.labels_group) self.on_resize(width, height) def launch_server(self): if os.name == 'nt': subprocess.Popen([sys.executable, "server.py"], creationflags=subprocess.CREATE_NEW_CONSOLE) else: subprocess.Popen([sys.executable, "server.py"]) localip = [ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][0] self.text_input.text = localip G.IP_ADDRESS = localip def on_resize(self, width, height): MenuView.on_resize(self, width, height) self.text_input.resize(x=self.frame.x + (self.frame.width - self.text_input.width) / 2 + 5, y=self.frame.y + (self.frame.height) / 2 + 75, width=150)
def setup(self): if G.SINGLEPLAYER: try: print 'Starting internal server...' # TODO: create world menu G.SAVE_FILENAME = "world" start_server(internal=True) sock = socket.socket() sock.connect(("localhost", 1486)) except socket.error as e: print "Socket Error:", e #Otherwise back to the main menu we go return False except Exception as e: print 'Unable to start internal server' import traceback traceback.print_exc() return False else: try: #Make sure the address they want to connect to works ipport = G.IP_ADDRESS.split(":") if len(ipport) == 1: ipport.append(1486) sock = socket.socket() sock.connect((tuple(ipport))) except socket.error as e: print "Socket Error:", e #Otherwise back to the main menu we go return False self.init_gl() sky_rotation = -20.0 # -20.0 # TERRAIN_CHOICE = self.biome_generator.get_biome_type(sector[0], sector[2]) default_skybox = 'skydome.jpg' #if TERRAIN_CHOICE == G.NETHER: # default_skybox = 'skydome_nether.jpg' #else: # default_skybox = 'skybox.jpg' print 'loading ' + default_skybox self.skydome = Skydome( 'resources/' + default_skybox, #'resources/skydome.jpg', 0.7, 100.0, sky_rotation, ) self.player_ids = { } # Dict of all players this session, indexes are their ID's [0: first Player on server,] self.focus_block = Block(width=1.05, height=1.05) self.earth = vec(0.8, 0.8, 0.8, 1.0) self.white = vec(1.0, 1.0, 1.0, 1.0) self.ambient = vec(1.0, 1.0, 1.0, 1.0) self.polished = GLfloat(100.0) self.crack_batch = pyglet.graphics.Batch() #if G.DISABLE_SAVE and world_exists(G.game_dir, G.SAVE_FILENAME): # open_world(self, G.game_dir, G.SAVE_FILENAME) self.world = World() self.packetreceiver = PacketReceiver(self.world, self, sock) self.world.packetreceiver = self.packetreceiver G.CLIENT = self.packetreceiver self.packetreceiver.start() #Get our position from the server self.packetreceiver.request_spawnpos() #Since we don't know it yet, lets disable self.update, or we'll load the wrong chunks and fall self.update_disabled = self.update self.update = lambda dt: None #We'll re-enable it when the server tells us where we should be self.player = Player(game_mode=G.GAME_MODE) print('Game mode: ' + self.player.game_mode) self.item_list = ItemSelector(self, self.player, self.world) self.inventory_list = InventorySelector(self, self.player, self.world) self.item_list.on_resize(self.window.width, self.window.height) self.inventory_list.on_resize(self.window.width, self.window.height) self.text_input = TextWidget(self.window, '', 0, 0, self.window.width, visible=False, font_name=G.CHAT_FONT) self.text_input.push_handlers(on_toggled=self.on_text_input_toggled, key_released=self.text_input_callback) self.chat_box = TextWidget(self.window, '', 0, self.text_input.y + self.text_input.height + 50, self.window.width / 2, height=min(300, self.window.height / 3), visible=False, multi_line=True, readonly=True, font_name=G.CHAT_FONT, text_color=(255, 255, 255, 255), background_color=(0, 0, 0, 100), enable_escape=True) self.camera = Camera3D(target=self.player) if G.HUD_ENABLED: self.label = pyglet.text.Label('', font_name='Arial', font_size=8, x=10, y=self.window.height - 10, anchor_x='left', anchor_y='top', color=(255, 255, 255, 255)) #if G.DEBUG_TEXT_ENABLED: # self.debug_text = TextWidget(self.window, '', # 0, self.window.height - 300, # 500, 300, # visible=True, multi_line=True, readonly=True, # font_name='Arial', font_size=10, # text_color=(255, 255, 255, 255), # background_color=(0, 0, 0, 0)) pyglet.clock.schedule_interval_soft(self.world.process_queue, 1.0 / G.MAX_FPS) pyglet.clock.schedule_interval_soft(self.world.hide_sectors, 10.0, self.player) return True
class GameController(Controller): def __init__(self, window): super(GameController, self).__init__(window) self.sector, self.highlighted_block, self.crack, self.last_key = ( None, ) * 4 self.bg_red, self.bg_green, self.bg_blue = (0.0, ) * 3 self.mouse_pressed, self.sorted = (False, ) * 2 self.count, self.block_damage = (0, ) * 2 self.light_y, self.light_z = (1.0, ) * 2 self.time_of_day = 0.0 self.hour_deg = 15.0 self.clock = 6 self.back_to_main_menu = threading.Event() def update(self, dt): if self.back_to_main_menu.isSet(): self.switch_controller_class(MainMenuController) return self.update_sector(dt) self.update_player(dt) self.update_mouse(dt) self.update_time() self.camera.update(dt) def update_sector(self, dt): sector = sectorize(self.player.position) if sector != self.sector: self.world.change_sectors(sector) # When the world is loaded, show every visible sector. if self.sector is None: self.world.process_entire_queue() self.sector = sector def update_player(self, dt): m = 8 df = min(dt, 0.2) for _ in xrange(m): self.player.update(df / m, self) for ply in self.player_ids.itervalues(): for _ in xrange(m): ply.update(df / m, self) momentum = self.player.get_motion_vector( 15 if self.player.flying else 5 * self.player.current_density) if momentum != self.player.momentum_previous: self.player.momentum_previous = momentum self.packetreceiver.send_movement(momentum, self.player.position) def update_mouse(self, dt): if self.mouse_pressed: vector = self.player.get_sight_vector() block, previous = self.world.hit_test(self.player.position, vector, self.player.attack_range) self.set_highlighted_block(block) if self.highlighted_block: hit_block = self.world[self.highlighted_block] if hit_block.hardness >= 0: self.update_block_damage(dt, hit_block) self.update_block_remove(dt, hit_block) def update_block_damage(self, dt, hit_block): multiplier = 1 current_item = self.item_list.get_current_block() if current_item is not None: if isinstance(current_item, Tool): # tool if current_item.tool_type == hit_block.digging_tool: multiplier = current_item.multiplier self.block_damage += self.player.attack_power * dt * multiplier def update_block_remove(self, dt, hit_block): if self.block_damage >= hit_block.hardness: self.world.remove_block(self.player, self.highlighted_block) self.set_highlighted_block(None) if getattr(self.item_list.get_current_block_item(), 'durability', -1) != -1: self.item_list.get_current_block_item().durability -= 1 if self.item_list.get_current_block_item().durability <= 0: self.item_list.remove_current_block() self.item_list.update_items() if hit_block.drop_id is None: return if type(hit_block.drop_id) == list: for index, item in enumerate(hit_block.drop_id): if not self.player.add_item( item, quantity=hit_block.drop_quantity[index]): return elif not self.player.add_item(hit_block.drop_id, quantity=hit_block.drop_quantity): return self.item_list.update_items() self.inventory_list.update_items() def init_gl(self): glEnable(GL_ALPHA_TEST) glAlphaFunc(GL_GREATER, 0.1) glEnable(GL_COLOR_MATERIAL) glEnable(GL_BLEND) glEnable(GL_LINE_SMOOTH) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) glEnable(GL_POLYGON_SMOOTH) glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST) #glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FALSE) #glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FALSE) #glClampColorARB(GL_CLAMP_READ_COLOR_ARB, GL_FALSE) #glClearColor(0, 0, 0, 0) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) def setup(self): if G.SINGLEPLAYER: try: print 'Starting internal server...' # TODO: create world menu G.SAVE_FILENAME = "world" start_server(internal=True) sock = socket.socket() sock.connect(("localhost", 1486)) except socket.error as e: print "Socket Error:", e #Otherwise back to the main menu we go return False except Exception as e: print 'Unable to start internal server' import traceback traceback.print_exc() return False else: try: #Make sure the address they want to connect to works ipport = G.IP_ADDRESS.split(":") if len(ipport) == 1: ipport.append(1486) sock = socket.socket() sock.connect((tuple(ipport))) except socket.error as e: print "Socket Error:", e #Otherwise back to the main menu we go return False self.init_gl() sky_rotation = -20.0 # -20.0 # TERRAIN_CHOICE = self.biome_generator.get_biome_type(sector[0], sector[2]) default_skybox = 'skydome.jpg' #if TERRAIN_CHOICE == G.NETHER: # default_skybox = 'skydome_nether.jpg' #else: # default_skybox = 'skybox.jpg' print 'loading ' + default_skybox self.skydome = Skydome( 'resources/' + default_skybox, #'resources/skydome.jpg', 0.7, 100.0, sky_rotation, ) self.player_ids = { } # Dict of all players this session, indexes are their ID's [0: first Player on server,] self.focus_block = Block(width=1.05, height=1.05) self.earth = vec(0.8, 0.8, 0.8, 1.0) self.white = vec(1.0, 1.0, 1.0, 1.0) self.ambient = vec(1.0, 1.0, 1.0, 1.0) self.polished = GLfloat(100.0) self.crack_batch = pyglet.graphics.Batch() #if G.DISABLE_SAVE and world_exists(G.game_dir, G.SAVE_FILENAME): # open_world(self, G.game_dir, G.SAVE_FILENAME) self.world = World() self.packetreceiver = PacketReceiver(self.world, self, sock) self.world.packetreceiver = self.packetreceiver G.CLIENT = self.packetreceiver self.packetreceiver.start() #Get our position from the server self.packetreceiver.request_spawnpos() #Since we don't know it yet, lets disable self.update, or we'll load the wrong chunks and fall self.update_disabled = self.update self.update = lambda dt: None #We'll re-enable it when the server tells us where we should be self.player = Player(game_mode=G.GAME_MODE) print('Game mode: ' + self.player.game_mode) self.item_list = ItemSelector(self, self.player, self.world) self.inventory_list = InventorySelector(self, self.player, self.world) self.item_list.on_resize(self.window.width, self.window.height) self.inventory_list.on_resize(self.window.width, self.window.height) self.text_input = TextWidget(self.window, '', 0, 0, self.window.width, visible=False, font_name=G.CHAT_FONT) self.text_input.push_handlers(on_toggled=self.on_text_input_toggled, key_released=self.text_input_callback) self.chat_box = TextWidget(self.window, '', 0, self.text_input.y + self.text_input.height + 50, self.window.width / 2, height=min(300, self.window.height / 3), visible=False, multi_line=True, readonly=True, font_name=G.CHAT_FONT, text_color=(255, 255, 255, 255), background_color=(0, 0, 0, 100), enable_escape=True) self.camera = Camera3D(target=self.player) if G.HUD_ENABLED: self.label = pyglet.text.Label('', font_name='Arial', font_size=8, x=10, y=self.window.height - 10, anchor_x='left', anchor_y='top', color=(255, 255, 255, 255)) #if G.DEBUG_TEXT_ENABLED: # self.debug_text = TextWidget(self.window, '', # 0, self.window.height - 300, # 500, 300, # visible=True, multi_line=True, readonly=True, # font_name='Arial', font_size=10, # text_color=(255, 255, 255, 255), # background_color=(0, 0, 0, 0)) pyglet.clock.schedule_interval_soft(self.world.process_queue, 1.0 / G.MAX_FPS) pyglet.clock.schedule_interval_soft(self.world.hide_sectors, 10.0, self.player) return True def update_time(self): """ The idle function advances the time of day. The day has 24 hours, from sunrise to sunset and from sunrise to second sunset. The time of day is converted to degrees and then to radians. """ if not self.window.exclusive: return time_of_day = self.time_of_day if self.time_of_day < 12.0 \ else 24.0 - self.time_of_day if time_of_day <= 2.5: self.time_of_day += 1.0 / G.TIME_RATE time_of_day += 1.0 / G.TIME_RATE self.count += 1 else: self.time_of_day += 20.0 / G.TIME_RATE time_of_day += 20.0 / G.TIME_RATE self.count += 1.0 / 20.0 if self.time_of_day > 24.0: self.time_of_day = 0.0 time_of_day = 0.0 side = len(self.world.sectors) * 2.0 self.light_y = 2.0 * side * sin( time_of_day * self.hour_deg * G.DEG_RAD) self.light_z = 2.0 * side * cos( time_of_day * self.hour_deg * G.DEG_RAD) if time_of_day <= 2.5: ambient_value = 1.0 else: ambient_value = 1 - (time_of_day - 2.25) / 9.5 self.ambient = vec(ambient_value, ambient_value, ambient_value, 1.0) # Calculate sky colour according to time of day. sin_t = sin(pi * time_of_day / 12.0) self.bg_red = 0.1 * (1.0 - sin_t) self.bg_green = 0.9 * sin_t self.bg_blue = min(sin_t + 0.4, 0.8) if fmod(self.count / 2, G.TIME_RATE) == 0: if self.clock == 18: self.clock = 6 else: self.clock += 1 def set_highlighted_block(self, block): if self.highlighted_block == block: return self.highlighted_block = block self.block_damage = 0 if self.crack: self.crack.delete() self.crack = None def on_mouse_press(self, x, y, button, modifiers): if self.window.exclusive: vector = self.player.get_sight_vector() block, previous = self.world.hit_test(self.player.position, vector, self.player.attack_range) if button == pyglet.window.mouse.LEFT: self.on_mouse_press_left(block, x, y, button, modifiers) else: self.on_mouse_press_right(block, previous, x, y, button, modifiers) else: self.window.set_exclusive_mouse(True) def on_mouse_press_left(self, block, x, y, button, modifiers): if block: self.mouse_pressed = True self.set_highlighted_block(None) def on_mouse_press_right(self, block, previous, x, y, button, modifiers): if previous: hit_block = self.world[block] if hit_block.id == craft_block.id: self.inventory_list.switch_mode(1) self.inventory_list.toggle(False) elif hit_block.id == furnace_block.id: self.inventory_list.switch_mode(2) self.inventory_list.set_furnace(hit_block) self.inventory_list.toggle(False) elif hit_block.density >= 1: self.put_block(previous) elif self.item_list.get_current_block() and getattr( self.item_list.get_current_block(), 'regenerated_health', 0) != 0 and self.player.health < self.player.max_health: self.eat_item() def put_block(self, previous): # FIXME - Better name... current_block = self.item_list.get_current_block() if current_block is not None: # if current block is an item, # call its on_right_click() method to handle this event if current_block.id >= G.ITEM_ID_MIN: if current_block.on_right_click(self.world, self.player): self.item_list.get_current_block_item().change_amount(-1) self.item_list.update_health() self.item_list.update_items() else: localx, localy, localz = imap(operator.sub, previous, normalize(self.player.position)) if localx != 0 or localz != 0 or (localy != 0 and localy != -1): self.world.add_block(previous, current_block) self.item_list.remove_current_block() def eat_item(self): # FIXME - Better name (2)... self.player.change_health( self.item_list.get_current_block().regenerated_health) self.item_list.get_current_block_item().change_amount(-1) self.item_list.update_health() self.item_list.update_items() def on_mouse_release(self, x, y, button, modifiers): if self.window.exclusive: self.set_highlighted_block(None) self.mouse_pressed = False def on_mouse_motion(self, x, y, dx, dy): if self.window.exclusive: m = 0.15 x, y = self.player.rotation x, y = x + dx * m, y + dy * m y = max(-90, min(90, y)) self.player.rotation = (x, y) self.camera.rotate(x, y) def on_mouse_drag(self, x, y, dx, dy, button, modifiers): if button == pyglet.window.mouse.LEFT: self.on_mouse_motion(x, y, dx, dy) def on_key_press(self, symbol, modifiers): if symbol == G.TOGGLE_HUD_KEY: G.HUD_ENABLED = not G.HUD_ENABLED if symbol == G.TOGGLE_DEBUG_TEXT_KEY: #self.debug_text.visible = not self.debug_text.visible G.DEBUG_TEXT_ENABLED = not G.DEBUG_TEXT_ENABLED elif symbol == G.INVENTORY_SORT_KEY: if self.last_key == symbol and not self.sorted: self.player.quick_slots.sort() self.player.inventory.sort() self.sorted = True else: self.player.quick_slots.change_sort_mode() self.player.inventory.change_sort_mode() self.item_list.update_items() self.inventory_list.update_items() elif symbol == G.INVENTORY_KEY: self.set_highlighted_block(None) self.mouse_pressed = False self.inventory_list.toggle() elif symbol == G.SOUND_UP_KEY: G.EFFECT_VOLUME = min(G.EFFECT_VOLUME + .1, 1) elif symbol == G.SOUND_DOWN_KEY: G.EFFECT_VOLUME = max(G.EFFECT_VOLUME - .1, 0) elif symbol == G.SCREENCAP_KEY: # dedicated screencap key now = datetime.datetime.now() dt = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute, now.second) st = dt.strftime('%Y-%m-%d_%H.%M.%S') filename = str(st) + '.png' if not os.path.exists('screencaptures'): os.makedirs('screencaptures') path = 'screencaptures/' + filename pyglet.image.get_buffer_manager().get_color_buffer().save(path) elif symbol == G.SHOWMAP_KEY: self.show_map() self.last_key = symbol def on_key_release(self, symbol, modifiers): if symbol == G.TALK_KEY: self.toggle_text_input() return pyglet.event.EVENT_HANDLED def on_resize(self, width, height): if G.HUD_ENABLED: self.label.y = height - 10 self.text_input.resize(x=0, y=0, width=self.window.width) self.chat_box.resize(x=0, y=self.text_input.y + self.text_input.height + 50, width=self.window.width / 2, height=min(300, self.window.height / 3)) #self.debug_text.resize(0, self.window.height - 300, # 500, 300) def set_3d(self): width, height = self.window.get_size() glEnable(GL_DEPTH_TEST) glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(G.FOV, width / float(height), G.NEAR_CLIP_DISTANCE, G.FAR_CLIP_DISTANCE) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glPushMatrix() self.camera.look() self.skydome.draw() glPopMatrix() self.camera.transform() def clear(self): glClearColor(self.bg_red, self.bg_green, self.bg_blue, 1.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) def on_draw(self): self.clear() #self.window.clear() self.set_3d() #glColor3d(1, 1, 1) self.world.batch.draw() self.world.transparency_batch.draw() glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) self.crack_batch.draw() glDisable(GL_BLEND) self.draw_focused_block() for ply in self.player_ids.itervalues(): ply.model.draw() self.set_2d() if G.HUD_ENABLED: self.draw_label() self.item_list.draw() self.inventory_list.draw() #if G.DEBUG_TEXT_ENABLED: # self.update_label() #self.debug_text.draw() self.text_input.draw() glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) self.chat_box.draw() glDisable(GL_BLEND) def show_cracks(self, hit_block, vertex_data): if self.block_damage: # also show the cracks crack_level = int(CRACK_LEVELS * self.block_damage / hit_block.hardness) # range: [0, CRACK_LEVELS[ if crack_level >= CRACK_LEVELS: return texture_data = crack_textures.texture_data[crack_level] count = len(texture_data) / 2 if self.crack: self.crack.delete() self.crack = self.crack_batch.add(count, GL_QUADS, crack_textures.group, ('v3f/static', vertex_data), ('t2f/static', texture_data)) def draw_focused_block(self): glDisable(GL_LIGHTING) vector = self.player.get_sight_vector() position = self.world.hit_test(self.player.position, vector, self.player.attack_range)[0] if position: hit_block = self.world[position] if hit_block.density >= 1: self.focus_block.width = hit_block.width * 1.05 self.focus_block.height = hit_block.height * 1.05 vertex_data = self.focus_block.get_vertices(*position) if hit_block.hardness > 0.0: self.show_cracks(hit_block, vertex_data) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glColor4f(0.0, 0.0, 0.0, 0.4) glLineWidth(2.0) glDisable(GL_TEXTURE_2D) glDepthMask(False) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) pyglet.graphics.draw(24, GL_QUADS, ('v3f/static', vertex_data)) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glDepthMask(True) glEnable(GL_TEXTURE_2D) glDisable(GL_BLEND) def draw_label(self): x, y, z = self.player.position self.label.text = 'Time:%.1f Inaccurate FPS:%02d (%.2f, %.2f, %.2f) Blocks Shown: %d / %d sector_packets:%d'\ % (self.time_of_day if (self.time_of_day < 12.0) else (24.0 - self.time_of_day), pyglet.clock.get_fps(), x, y, z, len(self.world._shown), len(self.world), len(self.world.sector_packets)) self.label.draw() def update_label(self): x, y, z = self.player.position self.debug_text.clear() self.debug_text.write_line(' '.join((G.APP_NAME, str(G.APP_VERSION)))) self.debug_text.write_line('Time:%.1f Inaccurate FPS:%02d Blocks Shown: %d / %d sector_packets:%d'\ % (self.time_of_day if (self.time_of_day < 12.0) else (24.0 - self.time_of_day), pyglet.clock.get_fps(), len(self.world._shown), len(self.world), len(self.world.sector_packets))) self.debug_text.write_line('x: %.2f, sector: %d' % (x, x // G.SECTOR_SIZE)) self.debug_text.write_line('y: %.2f, sector: %d' % (y, y // G.SECTOR_SIZE)) self.debug_text.write_line('z: %.2f, sector: %d' % (z, z // G.SECTOR_SIZE)) #dirs = ['East', 'South', 'West', 'North'] #vec, direction, angle = self.player.get_sight_direction() #dx, dy, dz = vec #self.debug_text.write_line('Direction: (%.2f, %.2f, %.2f) %d(%s) %.2f' % (dx, dy, dz, direction, dirs[direction], angle)) def write_line(self, text, **kwargs): self.chat_box.write_line(text, **kwargs) def text_input_callback(self, symbol, modifier): if symbol == G.VALIDATE_KEY: txt = self.text_input.text.replace('\n', '') self.text_input.clear() if txt: self.world.packetreceiver.send_chat(txt) return pyglet.event.EVENT_HANDLED def hide_chat_box(self, dt): self.chat_box.toggle(False) def on_text_input_toggled(self): pyglet.clock.unschedule(self.hide_chat_box) # Disable the fade timer self.chat_box.toggle( state=self.text_input.visible ) # Pass through the state incase chat_box was already visible if self.chat_box.visible: self.chat_box.focused = True # Allow scrolling self.window.push_handlers(self.chat_box) else: self.chat_box.focused = False self.window.remove_handlers(self.chat_box) def toggle_text_input(self): self.text_input.toggle() if self.text_input.visible: self.player.velocity = 0 self.player.strafe = [0, 0] self.window.push_handlers(self.text_input) self.text_input.focus() else: self.window.remove_handlers(self.text_input) def push_handlers(self): if self.setup(): self.window.push_handlers(self.camera) self.window.push_handlers(self.player) self.window.push_handlers(self) self.window.push_handlers(self.item_list) self.window.push_handlers(self.inventory_list) else: self.switch_controller_class(MainMenuController) def pop_handlers(self): while self.window._event_stack: self.window.pop_handlers() def on_close(self): G.save_config() self.world.packetreceiver.stop( ) # Disconnect from the server so the process can close def show_map(self): print("map called...") # taken from Nebual's biome_explorer, this is ment to be a full screen map that uses mini tiles to make a full 2d map. with open(os.path.join(G.game_dir, "world", "seed"), "rb") as f: SEED = f.read() b = BiomeGenerator(SEED) x, y, z = self.player.position curx = x cury = y xsize = 79 ysize = 28 pbatch = pyglet.graphics.Batch() pgroup = pyglet.graphics.OrderedGroup(1) DESERT, PLAINS, MOUNTAINS, SNOW, FOREST = range(5) letters = ["D", "P", "M", "S", "F"] # temp background pic... image = load_image('resources', 'textures', 'main_menu_background.png') #map_frame = image_sprite(image, pbatch, 0, y=G.WINDOW_WIDTH, height=G.WINDOW_HEIGHT) #sprite = pyglet.sprite.Sprite(image) #sprite.image(image) #sprite.visible = True # map_frame.draw() # map_frame.visible = True for y in range(int(cury), int(cury + ysize)): for x in range(int(curx), int(curx + xsize)): #string += letters[b.get_biome_type(x,y)] tmap = letters[b.get_biome_type(x, y)] tile_map = load_image('resources', 'textures', tmap + '.png') tile_map.anchor_x = x * 8 tile_map.anchor_Y = y * 8 sprite = pyglet.sprite.Sprite(tile_map, x=x * 8, y=y * 8, batch=pbatch) game_map = image_sprite(tile_map, pbatch, pgroup, x * 8, y * 8, 8, 8) game_map = pyglet.sprite.Sprite(image, x=G.WINDOW_WIDTH, y=G.WINDOW_HEIGHT, batch=pbatch, group=pgroup) game_map = pyglet.sprite.Sprite(tile_map, x=x * 8, y=y * 8, batch=pbatch, group=pgroup) tile_map.blit(x * 8, y * 8) #tile_map.draw() #map.append(tmap) game_map.draw() pbatch.draw()
def setup(self): try: #Make sure the address they want to connect to works ipport = G.IP_ADDRESS.split(":") if len(ipport) == 1: ipport.append(1486) sock = socket.socket() sock.connect(tuple(ipport)) except socket.error as e: print "Socket Error:", e #Otherwise back to the main menu we go return False self.init_gl() sky_rotation = -20.0 # -20.0 print 'loading sky' self.skydome = Skydome( 'resources/skydome.jpg', 0.7, 100.0, sky_rotation, ) lux = 600.0 self.focus_block = Block(width=1.05, height=1.05) self.earth = vec(0.8, 0.8, 0.8, 1.0) self.white = vec(1.0, 1.0, 1.0, 1.0) self.ambient = vec(1.0, 1.0, 1.0, 1.0) self.polished = GLfloat(100.0) self.crack_batch = pyglet.graphics.Batch() #if G.DISABLE_SAVE and world_exists(G.game_dir, G.SAVE_FILENAME): # open_world(self, G.game_dir, G.SAVE_FILENAME) self.world = World() self.packetreceiver = PacketReceiver(self.world, self, sock) self.world.packetreceiver = self.packetreceiver self.packetreceiver.start() #Get our position from the server self.packetreceiver.request_spawnpos() #Since we don't know it yet, lets disable self.update, or we'll load the wrong chunks and fall self.update_disabled = self.update self.update = lambda dt: None #We'll re-enable it when the server tells us where we should be self.player = Player((0,0,0), (-20, 0), game_mode=G.GAME_MODE) print('Game mode: ' + self.player.game_mode) self.item_list = ItemSelector(self, self.player, self.world) self.inventory_list = InventorySelector(self, self.player, self.world) self.item_list.on_resize(self.window.width, self.window.height) self.inventory_list.on_resize(self.window.width, self.window.height) self.text_input = TextWidget(self.window, '', 0, 0, self.window.width, visible=False, font_name='Arial') self.text_input.push_handlers(on_toggled=self.on_text_input_toggled, key_released=self.text_input_callback) self.chat_box = TextWidget(self.window, '', 0, self.text_input.y + self.text_input.height + 50, self.window.width / 2, height=min(300, self.window.height / 3), visible=False, multi_line=True, readonly=True, font_size=14, font_name='Arial', background_color=(64,64,64,200)) self.camera = Camera3D(target=self.player) if G.HUD_ENABLED: self.label = pyglet.text.Label( '', font_name='Arial', font_size=8, x=10, y=self.window.height - 10, anchor_x='left', anchor_y='top', color=(255, 255, 255, 255)) pyglet.clock.schedule_interval_soft(self.world.process_queue, 1.0 / G.MAX_FPS) pyglet.clock.schedule_interval_soft(self.world.hide_sectors, 1.0, self.player) return True
class GameController(Controller): def __init__(self, window): super(GameController, self).__init__(window) self.sector, self.highlighted_block, self.crack, self.last_key = (None,) * 4 self.bg_red, self.bg_green, self.bg_blue = (0.0,) * 3 self.mouse_pressed, self.sorted = (False,) * 2 self.count, self.block_damage = (0,) * 2 self.light_y, self.light_z = (1.0,) * 2 self.time_of_day = 0.0 self.hour_deg = 15.0 self.clock = 6 self.back_to_main_menu = threading.Event() def update(self, dt): if self.back_to_main_menu.isSet(): self.switch_controller_class(MainMenuController) return self.update_sector(dt) self.update_player(dt) self.update_mouse(dt) self.update_time() self.camera.update(dt) def update_sector(self, dt): sector = sectorize(self.player.position) if sector != self.sector: self.world.change_sectors(sector) # When the world is loaded, show every visible sector. if self.sector is None: self.world.process_entire_queue() self.sector = sector def update_player(self, dt): m = 8 df = min(dt, 0.2) for _ in xrange(m): self.player.update(df / m, self) def update_mouse(self, dt): if self.mouse_pressed: vector = self.player.get_sight_vector() block, previous = self.world.hit_test(self.player.position, vector, self.player.attack_range) self.set_highlighted_block(block) if self.highlighted_block: hit_block = self.world[self.highlighted_block] if hit_block.hardness >= 0: self.update_block_damage(dt, hit_block) self.update_block_remove(dt, hit_block) def update_block_damage(self, dt, hit_block): multiplier = 1 current_item = self.item_list.get_current_block() if current_item is not None: if isinstance(current_item, Tool): # tool if current_item.tool_type == hit_block.digging_tool: multiplier = current_item.multiplier self.block_damage += self.player.attack_power * dt * multiplier def update_block_remove(self, dt, hit_block): if self.block_damage >= hit_block.hardness: self.world.remove_block(self.player, self.highlighted_block) self.set_highlighted_block(None) if getattr(self.item_list.get_current_block_item(), 'durability', -1) != -1: self.item_list.get_current_block_item().durability -= 1 if self.item_list.get_current_block_item().durability <= 0: self.item_list.remove_current_block() self.item_list.update_items() if hit_block.drop_id is not None \ and self.player.add_item(hit_block.drop_id): self.item_list.update_items() self.inventory_list.update_items() def init_gl(self): glEnable(GL_ALPHA_TEST) glAlphaFunc(GL_GREATER, 0.1) glEnable(GL_COLOR_MATERIAL) glEnable(GL_BLEND) glEnable(GL_LINE_SMOOTH) #glEnable(GL_POLYGON_SMOOTH) #glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FALSE) glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FALSE) glClampColorARB(GL_CLAMP_READ_COLOR_ARB, GL_FALSE) glClearColor(0, 0, 0, 0) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) def setup(self): try: #Make sure the address they want to connect to works ipport = G.IP_ADDRESS.split(":") if len(ipport) == 1: ipport.append(1486) sock = socket.socket() sock.connect(tuple(ipport)) except socket.error as e: print "Socket Error:", e #Otherwise back to the main menu we go return False self.init_gl() sky_rotation = -20.0 # -20.0 print 'loading sky' self.skydome = Skydome( 'resources/skydome.jpg', 0.7, 100.0, sky_rotation, ) lux = 600.0 self.focus_block = Block(width=1.05, height=1.05) self.earth = vec(0.8, 0.8, 0.8, 1.0) self.white = vec(1.0, 1.0, 1.0, 1.0) self.ambient = vec(1.0, 1.0, 1.0, 1.0) self.polished = GLfloat(100.0) self.crack_batch = pyglet.graphics.Batch() #if G.DISABLE_SAVE and world_exists(G.game_dir, G.SAVE_FILENAME): # open_world(self, G.game_dir, G.SAVE_FILENAME) self.world = World() self.packetreceiver = PacketReceiver(self.world, self, sock) self.world.packetreceiver = self.packetreceiver self.packetreceiver.start() #Get our position from the server self.packetreceiver.request_spawnpos() #Since we don't know it yet, lets disable self.update, or we'll load the wrong chunks and fall self.update_disabled = self.update self.update = lambda dt: None #We'll re-enable it when the server tells us where we should be self.player = Player((0,0,0), (-20, 0), game_mode=G.GAME_MODE) print('Game mode: ' + self.player.game_mode) self.item_list = ItemSelector(self, self.player, self.world) self.inventory_list = InventorySelector(self, self.player, self.world) self.item_list.on_resize(self.window.width, self.window.height) self.inventory_list.on_resize(self.window.width, self.window.height) self.text_input = TextWidget(self.window, '', 0, 0, self.window.width, visible=False, font_name='Arial') self.text_input.push_handlers(on_toggled=self.on_text_input_toggled, key_released=self.text_input_callback) self.chat_box = TextWidget(self.window, '', 0, self.text_input.y + self.text_input.height + 50, self.window.width / 2, height=min(300, self.window.height / 3), visible=False, multi_line=True, readonly=True, font_size=14, font_name='Arial', background_color=(64,64,64,200)) self.camera = Camera3D(target=self.player) if G.HUD_ENABLED: self.label = pyglet.text.Label( '', font_name='Arial', font_size=8, x=10, y=self.window.height - 10, anchor_x='left', anchor_y='top', color=(255, 255, 255, 255)) pyglet.clock.schedule_interval_soft(self.world.process_queue, 1.0 / G.MAX_FPS) pyglet.clock.schedule_interval_soft(self.world.hide_sectors, 1.0, self.player) return True def update_time(self): """ The idle function advances the time of day. The day has 24 hours, from sunrise to sunset and from sunrise to second sunset. The time of day is converted to degrees and then to radians. """ if not self.window.exclusive: return time_of_day = self.time_of_day if self.time_of_day < 12.0 \ else 24.0 - self.time_of_day if time_of_day <= 2.5: self.time_of_day += 1.0 / G.TIME_RATE time_of_day += 1.0 / G.TIME_RATE self.count += 1 else: self.time_of_day += 20.0 / G.TIME_RATE time_of_day += 20.0 / G.TIME_RATE self.count += 1.0 / 20.0 if self.time_of_day > 24.0: self.time_of_day = 0.0 time_of_day = 0.0 side = len(self.world.sectors) * 2.0 self.light_y = 2.0 * side * sin(time_of_day * self.hour_deg * G.DEG_RAD) self.light_z = 2.0 * side * cos(time_of_day * self.hour_deg * G.DEG_RAD) if time_of_day <= 2.5: ambient_value = 1.0 else: ambient_value = 1 - (time_of_day - 2.25) / 9.5 self.ambient = vec(ambient_value, ambient_value, ambient_value, 1.0) # Calculate sky colour according to time of day. sin_t = sin(pi * time_of_day / 12.0) self.bg_red = 0.1 * (1.0 - sin_t) self.bg_green = 0.9 * sin_t self.bg_blue = min(sin_t + 0.4, 0.8) if fmod(self.count / 2, G.TIME_RATE) == 0: if self.clock == 18: self.clock = 6 else: self.clock += 1 def set_highlighted_block(self, block): if self.highlighted_block == block: return self.highlighted_block = block self.block_damage = 0 if self.crack: self.crack.delete() self.crack = None def on_mouse_press(self, x, y, button, modifiers): if self.window.exclusive: vector = self.player.get_sight_vector() block, previous = self.world.hit_test(self.player.position, vector, self.player.attack_range) if button == pyglet.window.mouse.LEFT: self.on_mouse_press_left(block, x, y, button, modifiers) else: self.on_mouse_press_right(block, previous, x, y, button, modifiers) else: self.window.set_exclusive_mouse(True) def on_mouse_press_left(self, block, x, y, button, modifiers): if block: self.mouse_pressed = True self.set_highlighted_block(None) def on_mouse_press_right(self, block, previous, x, y, button, modifiers): if previous: hit_block = self.world[block] if hit_block.id == craft_block.id: self.inventory_list.mode = 1 self.inventory_list.toggle(False) elif hit_block.id == furnace_block.id: self.inventory_list.mode = 2 self.inventory_list.set_furnace(hit_block) self.inventory_list.toggle(False) elif hit_block.density >= 1: self.put_block(previous) elif self.item_list.get_current_block() and getattr(self.item_list.get_current_block(), 'regenerated_health', 0) != 0 and self.player.health < self.player.max_health: self.eat_item() def put_block(self, previous): # FIXME - Better name... current_block = self.item_list.get_current_block() if current_block is not None: # if current block is an item, # call its on_right_click() method to handle this event if current_block.id >= G.ITEM_ID_MIN: if current_block.on_right_click(self.world, self.player): self.item_list.get_current_block_item().change_amount(-1) self.item_list.update_health() self.item_list.update_items() else: localx, localy, localz = imap(operator.sub,previous,normalize(self.player.position)) if localx != 0 or localz != 0 or (localy != 0 and localy != -1): self.world.add_block(previous, current_block) self.item_list.remove_current_block() def eat_item(self): # FIXME - Better name (2)... self.player.change_health(self.item_list.get_current_block().regenerated_health) self.item_list.get_current_block_item().change_amount(-1) self.item_list.update_health() self.item_list.update_items() def on_mouse_release(self, x, y, button, modifiers): if self.window.exclusive: self.set_highlighted_block(None) self.mouse_pressed = False def on_mouse_motion(self, x, y, dx, dy): if self.window.exclusive: m = 0.15 x, y = self.player.rotation x, y = x + dx * m, y + dy * m y = max(-90, min(90, y)) self.player.rotation = (x, y) self.camera.rotate(x, y) def on_mouse_drag(self, x, y, dx, dy, button, modifiers): if button == pyglet.window.mouse.LEFT: self.on_mouse_motion(x, y, dx, dy) def on_key_press(self, symbol, modifiers): if symbol == G.TOGGLE_HUD_KEY: G.HUD_ENABLED = not G.HUD_ENABLED elif symbol == G.INVENTORY_SORT_KEY: if self.last_key == symbol and not self.sorted: self.player.quick_slots.sort() self.player.inventory.sort() self.sorted = True else: self.player.quick_slots.change_sort_mode() self.player.inventory.change_sort_mode() self.item_list.update_items() self.inventory_list.update_items() elif symbol == G.INVENTORY_KEY: self.set_highlighted_block(None) self.mouse_pressed = False self.inventory_list.toggle() elif symbol == G.SOUND_UP_KEY: G.EFFECT_VOLUME = min(G.EFFECT_VOLUME + .1, 1) elif symbol == G.SOUND_DOWN_KEY: G.EFFECT_VOLUME = max(G.EFFECT_VOLUME - .1, 0) elif symbol == G.SCREENCAP_KEY: # dedicated screencap key now = datetime.datetime.now() dt = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute, now.second) st = dt.strftime('%Y-%m-%d_%H.%M.%S') filename = str(st) + '.png' if not os.path.exists('screencaptures'): os.makedirs('screencaptures') path = 'screencaptures/' + filename pyglet.image.get_buffer_manager().get_color_buffer().save(path) # self.send_info("Screen capture saved to '%s'" % path) self.last_key = symbol def on_key_release(self, symbol, modifiers): if symbol == G.TALK_KEY: self.toggle_text_input() return pyglet.event.EVENT_HANDLED def on_resize(self, width, height): if G.HUD_ENABLED: self.label.y = height - 10 self.text_input.resize(x=0, y=0, width=self.window.width) self.chat_box.resize(x=0, y=self.text_input.y + self.text_input.height + 50, width=self.window.width / 2, height=min(300, self.window.height/3)) def set_3d(self): width, height = self.window.get_size() glEnable(GL_DEPTH_TEST) glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(G.FOV, width / float(height), G.NEAR_CLIP_DISTANCE, G.FAR_CLIP_DISTANCE) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glPushMatrix() self.camera.look() self.skydome.draw() glPopMatrix() self.camera.transform() def clear(self): glClearColor(self.bg_red, self.bg_green, self.bg_blue, 1.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) def on_draw(self): self.clear() #self.window.clear() self.set_3d() #glColor3d(1, 1, 1) self.world.batch.draw() self.world.transparency_batch.draw() self.crack_batch.draw() self.draw_focused_block() self.set_2d() if G.HUD_ENABLED: self.draw_label() self.item_list.draw() self.inventory_list.draw() self.text_input.draw() self.chat_box.draw() def show_cracks(self, hit_block, vertex_data): if self.block_damage: # also show the cracks crack_level = int(CRACK_LEVELS * self.block_damage / hit_block.hardness) # range: [0, CRACK_LEVELS[ if crack_level >= CRACK_LEVELS: return texture_data = crack_textures.texture_data[crack_level] count = len(texture_data) / 2 if self.crack: self.crack.delete() self.crack = self.crack_batch.add(count, GL_QUADS, self.world.group, ('v3f/static', vertex_data), ('t2f/static', texture_data)) def draw_focused_block(self): glDisable(GL_LIGHTING) vector = self.player.get_sight_vector() position = self.world.hit_test(self.player.position, vector, self.player.attack_range)[0] if position: hit_block = self.world[position] if hit_block.density >= 1: self.focus_block.width = hit_block.width * 1.05 self.focus_block.height = hit_block.height * 1.05 vertex_data = self.focus_block.get_vertices(*position) if hit_block.hardness > 0.0: self.show_cracks(hit_block, vertex_data) glColor3d(0, 0, 0) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) pyglet.graphics.draw(24, GL_QUADS, ('v3f/static', vertex_data)) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) def draw_label(self): x, y, z = self.player.position self.label.text = 'Time:%.1f Inaccurate FPS:%02d (%.2f, %.2f, %.2f) Blocks Shown: %d / %d sector_packets:%d'\ % (self.time_of_day if (self.time_of_day < 12.0) else (24.0 - self.time_of_day), pyglet.clock.get_fps(), x, y, z, len(self.world._shown), len(self.world), len(self.world.sector_packets)) self.label.draw() def write_line(self, text, **kwargs): self.chat_box.write_line(text, **kwargs) def text_input_callback(self, symbol, modifier): if symbol == G.VALIDATE_KEY: txt = self.text_input.text.replace('\n', '') self.text_input.clear() if txt: self.world.packetreceiver.send_chat(txt) return pyglet.event.EVENT_HANDLED def hide_chat_box(self, dt): self.chat_box.toggle(False) def on_text_input_toggled(self): pyglet.clock.unschedule(self.hide_chat_box) # Disable the fade timer self.chat_box.toggle(state=self.text_input.visible) # Pass through the state incase chat_box was already visible if self.chat_box.visible: self.chat_box.focused = True # Allow scrolling self.window.push_handlers(self.chat_box) else: self.chat_box.focused = False self.window.remove_handlers(self.chat_box) def toggle_text_input(self): self.text_input.toggle() if self.text_input.visible: self.player.velocity = 0 self.player.strafe = [0, 0] self.window.push_handlers(self.text_input) self.text_input.focus() else: self.window.remove_handlers(self.text_input) def push_handlers(self): if self.setup(): self.window.push_handlers(self.camera) self.window.push_handlers(self.player) self.window.push_handlers(self) self.window.push_handlers(self.item_list) self.window.push_handlers(self.inventory_list) else: self.switch_controller_class(MainMenuController) def pop_handlers(self): while self.window._event_stack: self.window.pop_handlers() def on_close(self): G.save_config() self.world.packetreceiver.stop() # Disconnect from the server so the process can close
def setup(self): if G.SINGLEPLAYER: try: print 'Starting internal server...' # TODO: create world menu G.SAVE_FILENAME = "world" start_server(internal=True) sock = socket.socket() sock.connect(("localhost", 1486)) except socket.error as e: print "Socket Error:", e #Otherwise back to the main menu we go return False except Exception as e: print 'Unable to start internal server' import traceback traceback.print_exc() return False else: try: #Make sure the address they want to connect to works ipport = G.IP_ADDRESS.split(":") if len(ipport) == 1: ipport.append(1486) sock = socket.socket() sock.connect((tuple(ipport))) except socket.error as e: print "Socket Error:", e #Otherwise back to the main menu we go return False self.init_gl() sky_rotation = -20.0 # -20.0 # TERRAIN_CHOICE = self.biome_generator.get_biome_type(sector[0], sector[2]) default_skybox = 'skydome.jpg' #if TERRAIN_CHOICE == G.NETHER: # default_skybox = 'skydome_nether.jpg' #else: # default_skybox = 'skybox.jpg' print 'loading ' + default_skybox self.skydome = Skydome( 'resources/' + default_skybox, #'resources/skydome.jpg', 0.7, 100.0, sky_rotation, ) self.player_ids = {} # Dict of all players this session, indexes are their ID's [0: first Player on server,] self.focus_block = B.Block(width=1.05, height=1.05) self.earth = vec(0.8, 0.8, 0.8, 1.0) self.white = vec(1.0, 1.0, 1.0, 1.0) self.ambient = vec(1.0, 1.0, 1.0, 1.0) self.polished = GLfloat(100.0) self.crack_batch = pyglet.graphics.Batch() #if G.DISABLE_SAVE and world_exists(G.game_dir, G.SAVE_FILENAME): # open_world(self, G.game_dir, G.SAVE_FILENAME) self.world = World() self.packetreceiver = PacketReceiver(self.world, self, sock) self.world.packetreceiver = self.packetreceiver G.CLIENT = self.packetreceiver self.packetreceiver.start() #Get our position from the server self.packetreceiver.request_spawnpos() #Since we don't know it yet, lets disable self.update, or we'll load the wrong chunks and fall self.update_disabled = self.update self.update = lambda dt: None #We'll re-enable it when the server tells us where we should be self.player = Player(game_mode=G.GAME_MODE) print('Game mode: ' + self.player.game_mode) self.item_list = ItemSelector(self, self.player, self.world) self.inventory_list = InventorySelector(self, self.player, self.world) self.item_list.on_resize(self.window.width, self.window.height) self.inventory_list.on_resize(self.window.width, self.window.height) self.text_input = TextWidget(self.window, '', 0, 0, self.window.width, visible=False, font_name=G.CHAT_FONT) self.text_input.push_handlers(on_toggled=self.on_text_input_toggled, key_released=self.text_input_callback) self.chat_box = TextWidget(self.window, '', 0, self.text_input.y + self.text_input.height + 50, self.window.width / 2, height=min(300, self.window.height / 3), visible=False, multi_line=True, readonly=True, font_name=G.CHAT_FONT, text_color=(255, 255, 255, 255), background_color=(0, 0, 0, 100), enable_escape=True) self.camera = Camera3D(target=self.player) if G.HUD_ENABLED: self.label = pyglet.text.Label( '', font_name='Arial', font_size=8, x=10, y=self.window.height - 10, anchor_x='left', anchor_y='top', color=(255, 255, 255, 255)) pyglet.clock.schedule_interval_soft(self.world.process_queue, 1.0 / G.MAX_FPS) pyglet.clock.schedule_interval_soft(self.world.hide_sectors, 10.0, self.player) return True
class GameController(Controller): def __init__(self, window): super(GameController, self).__init__(window) self.sector, self.highlighted_block, self.crack, self.last_key = (None,) * 4 self.bg_red, self.bg_green, self.bg_blue = (0.0,) * 3 self.mouse_pressed, self.sorted = (False,) * 2 self.count, self.block_damage = (0,) * 2 self.light_y, self.light_z = (1.0,) * 2 self.time_of_day = 0.0 self.hour_deg = 15.0 self.clock = 6 self.back_to_main_menu = threading.Event() def update(self, dt): if self.back_to_main_menu.isSet(): self.switch_controller_class(MainMenuController) return self.update_sector(dt) self.update_player(dt) self.update_mouse(dt) self.update_time() self.camera.update(dt) def update_sector(self, dt): sector = sectorize(self.player.position) if sector != self.sector: self.world.change_sectors(sector) # When the world is loaded, show every visible sector. if self.sector is None: self.world.process_entire_queue() self.sector = sector def update_player(self, dt): m = 8 df = min(dt, 0.2) for _ in xrange(m): self.player.update(df / m, self) for ply in self.player_ids.itervalues(): for _ in xrange(m): ply.update(df / m, self) momentum = self.player.get_motion_vector(15 if self.player.flying else 5*self.player.current_density) if momentum != self.player.momentum_previous: self.player.momentum_previous = momentum self.packetreceiver.send_movement(momentum, self.player.position) def update_mouse(self, dt): if self.mouse_pressed: vector = self.player.get_sight_vector() block, previous = self.world.hit_test(self.player.position, vector, self.player.attack_range) self.set_highlighted_block(block) if self.highlighted_block: hit_block = self.world[self.highlighted_block] if hit_block.hardness >= 0: self.update_block_damage(dt, hit_block) self.update_block_remove(dt, hit_block) def update_block_damage(self, dt, hit_block): multiplier = 1 current_item = self.item_list.get_current_block() if current_item is not None: if isinstance(current_item, Tool): # tool if current_item.tool_type == hit_block.digging_tool: multiplier = current_item.multiplier self.block_damage += self.player.attack_power * dt * multiplier def update_block_remove(self, dt, hit_block): if self.block_damage >= hit_block.hardness: self.world.remove_block(self.player, self.highlighted_block) self.set_highlighted_block(None) if getattr(self.item_list.get_current_block_item(), 'durability', -1) != -1: self.item_list.get_current_block_item().durability -= 1 if self.item_list.get_current_block_item().durability <= 0: self.item_list.remove_current_block() self.item_list.update_items() if hit_block.drop_id is None: return if type(hit_block.drop_id) == list: for index, item in enumerate(hit_block.drop_id): if not self.player.add_item(item, quantity=hit_block.drop_quantity[index]): return elif not self.player.add_item(hit_block.drop_id, quantity=hit_block.drop_quantity): return self.item_list.update_items() self.inventory_list.update_items() def init_gl(self): glEnable(GL_ALPHA_TEST) glAlphaFunc(GL_GREATER, 0.1) glEnable(GL_COLOR_MATERIAL) glEnable(GL_BLEND) glEnable(GL_LINE_SMOOTH) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) glEnable(GL_POLYGON_SMOOTH) glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST) #glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FALSE) #glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FALSE) #glClampColorARB(GL_CLAMP_READ_COLOR_ARB, GL_FALSE) #glClearColor(0, 0, 0, 0) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) def setup(self): if G.SINGLEPLAYER: try: print 'Starting internal server...' # TODO: create world menu G.SAVE_FILENAME = "world" start_server(internal=True) sock = socket.socket() sock.connect(("localhost", 1486)) except socket.error as e: print "Socket Error:", e #Otherwise back to the main menu we go return False except Exception as e: print 'Unable to start internal server' import traceback traceback.print_exc() return False else: try: #Make sure the address they want to connect to works ipport = G.IP_ADDRESS.split(":") if len(ipport) == 1: ipport.append(1486) sock = socket.socket() sock.connect((tuple(ipport))) except socket.error as e: print "Socket Error:", e #Otherwise back to the main menu we go return False self.init_gl() sky_rotation = -20.0 # -20.0 # TERRAIN_CHOICE = self.biome_generator.get_biome_type(sector[0], sector[2]) default_skybox = 'skydome.jpg' #if TERRAIN_CHOICE == G.NETHER: # default_skybox = 'skydome_nether.jpg' #else: # default_skybox = 'skybox.jpg' print 'loading ' + default_skybox self.skydome = Skydome( 'resources/' + default_skybox, #'resources/skydome.jpg', 0.7, 100.0, sky_rotation, ) self.player_ids = {} # Dict of all players this session, indexes are their ID's [0: first Player on server,] self.focus_block = Block(width=1.05, height=1.05) self.earth = vec(0.8, 0.8, 0.8, 1.0) self.white = vec(1.0, 1.0, 1.0, 1.0) self.ambient = vec(1.0, 1.0, 1.0, 1.0) self.polished = GLfloat(100.0) self.crack_batch = pyglet.graphics.Batch() #if G.DISABLE_SAVE and world_exists(G.game_dir, G.SAVE_FILENAME): # open_world(self, G.game_dir, G.SAVE_FILENAME) self.world = World() self.packetreceiver = PacketReceiver(self.world, self, sock) self.world.packetreceiver = self.packetreceiver G.CLIENT = self.packetreceiver self.packetreceiver.start() #Get our position from the server self.packetreceiver.request_spawnpos() #Since we don't know it yet, lets disable self.update, or we'll load the wrong chunks and fall self.update_disabled = self.update self.update = lambda dt: None #We'll re-enable it when the server tells us where we should be self.player = Player(game_mode=G.GAME_MODE) print('Game mode: ' + self.player.game_mode) self.item_list = ItemSelector(self, self.player, self.world) self.inventory_list = InventorySelector(self, self.player, self.world) self.item_list.on_resize(self.window.width, self.window.height) self.inventory_list.on_resize(self.window.width, self.window.height) self.text_input = TextWidget(self.window, '', 0, 0, self.window.width, visible=False, font_name=G.CHAT_FONT) self.text_input.push_handlers(on_toggled=self.on_text_input_toggled, key_released=self.text_input_callback) self.chat_box = TextWidget(self.window, '', 0, self.text_input.y + self.text_input.height + 50, self.window.width / 2, height=min(300, self.window.height / 3), visible=False, multi_line=True, readonly=True, font_name=G.CHAT_FONT, text_color=(255, 255, 255, 255), background_color=(0, 0, 0, 100), enable_escape=True) self.camera = Camera3D(target=self.player) if G.HUD_ENABLED: self.label = pyglet.text.Label( '', font_name='Arial', font_size=8, x=10, y=self.window.height - 10, anchor_x='left', anchor_y='top', color=(255, 255, 255, 255)) #if G.DEBUG_TEXT_ENABLED: # self.debug_text = TextWidget(self.window, '', # 0, self.window.height - 300, # 500, 300, # visible=True, multi_line=True, readonly=True, # font_name='Arial', font_size=10, # text_color=(255, 255, 255, 255), # background_color=(0, 0, 0, 0)) pyglet.clock.schedule_interval_soft(self.world.process_queue, 1.0 / G.MAX_FPS) pyglet.clock.schedule_interval_soft(self.world.hide_sectors, 10.0, self.player) return True def update_time(self): """ The idle function advances the time of day. The day has 24 hours, from sunrise to sunset and from sunrise to second sunset. The time of day is converted to degrees and then to radians. """ if not self.window.exclusive: return time_of_day = self.time_of_day if self.time_of_day < 12.0 \ else 24.0 - self.time_of_day if time_of_day <= 2.5: self.time_of_day += 1.0 / G.TIME_RATE time_of_day += 1.0 / G.TIME_RATE self.count += 1 else: self.time_of_day += 20.0 / G.TIME_RATE time_of_day += 20.0 / G.TIME_RATE self.count += 1.0 / 20.0 if self.time_of_day > 24.0: self.time_of_day = 0.0 time_of_day = 0.0 side = len(self.world.sectors) * 2.0 self.light_y = 2.0 * side * sin(time_of_day * self.hour_deg * G.DEG_RAD) self.light_z = 2.0 * side * cos(time_of_day * self.hour_deg * G.DEG_RAD) if time_of_day <= 2.5: ambient_value = 1.0 else: ambient_value = 1 - (time_of_day - 2.25) / 9.5 self.ambient = vec(ambient_value, ambient_value, ambient_value, 1.0) # Calculate sky colour according to time of day. sin_t = sin(pi * time_of_day / 12.0) self.bg_red = 0.1 * (1.0 - sin_t) self.bg_green = 0.9 * sin_t self.bg_blue = min(sin_t + 0.4, 0.8) if fmod(self.count / 2, G.TIME_RATE) == 0: if self.clock == 18: self.clock = 6 else: self.clock += 1 self.skydome.update_time_of_day(self.time_of_day) def set_highlighted_block(self, block): if self.highlighted_block == block: return self.highlighted_block = block self.block_damage = 0 if self.crack: self.crack.delete() self.crack = None def on_mouse_press(self, x, y, button, modifiers): if self.window.exclusive: vector = self.player.get_sight_vector() block, previous = self.world.hit_test(self.player.position, vector, self.player.attack_range) if button == pyglet.window.mouse.LEFT: self.on_mouse_press_left(block, x, y, button, modifiers) else: self.on_mouse_press_right(block, previous, x, y, button, modifiers) else: self.window.set_exclusive_mouse(True) def on_mouse_press_left(self, block, x, y, button, modifiers): if block: self.mouse_pressed = True self.set_highlighted_block(None) def on_mouse_press_right(self, block, previous, x, y, button, modifiers): if previous: hit_block = self.world[block] if hit_block.id == craft_block.id: self.inventory_list.switch_mode(1) self.inventory_list.toggle(False) elif hit_block.id == furnace_block.id: self.inventory_list.switch_mode(2) self.inventory_list.set_furnace(hit_block) self.inventory_list.toggle(False) elif hit_block.density >= 1: self.put_block(previous) elif self.item_list.get_current_block() and getattr(self.item_list.get_current_block(), 'regenerated_health', 0) != 0 and self.player.health < self.player.max_health: self.eat_item() def put_block(self, previous): # FIXME - Better name... current_block = self.item_list.get_current_block() if current_block is not None: # if current block is an item, # call its on_right_click() method to handle this event if current_block.id >= G.ITEM_ID_MIN: if current_block.on_right_click(self.world, self.player): self.item_list.get_current_block_item().change_amount(-1) self.item_list.update_health() self.item_list.update_items() else: localx, localy, localz = imap(operator.sub,previous,normalize(self.player.position)) if localx != 0 or localz != 0 or (localy != 0 and localy != -1): self.world.add_block(previous, current_block) self.item_list.remove_current_block() def eat_item(self): # FIXME - Better name (2)... self.player.change_health(self.item_list.get_current_block().regenerated_health) self.item_list.get_current_block_item().change_amount(-1) self.item_list.update_health() self.item_list.update_items() def on_mouse_release(self, x, y, button, modifiers): if self.window.exclusive: self.set_highlighted_block(None) self.mouse_pressed = False def on_mouse_motion(self, x, y, dx, dy): if self.window.exclusive: m = 0.15 x, y = self.player.rotation x, y = x + dx * m, y + dy * m y = max(-90, min(90, y)) self.player.rotation = (x, y) self.camera.rotate(x, y) def on_mouse_drag(self, x, y, dx, dy, button, modifiers): if button == pyglet.window.mouse.LEFT: self.on_mouse_motion(x, y, dx, dy) def on_key_press(self, symbol, modifiers): if symbol == G.TOGGLE_HUD_KEY: G.HUD_ENABLED = not G.HUD_ENABLED if symbol == G.TOGGLE_DEBUG_TEXT_KEY: #self.debug_text.visible = not self.debug_text.visible G.DEBUG_TEXT_ENABLED = not G.DEBUG_TEXT_ENABLED elif symbol == G.INVENTORY_SORT_KEY: if self.last_key == symbol and not self.sorted: self.player.quick_slots.sort() self.player.inventory.sort() self.sorted = True else: self.player.quick_slots.change_sort_mode() self.player.inventory.change_sort_mode() self.item_list.update_items() self.inventory_list.update_items() elif symbol == G.INVENTORY_KEY: self.set_highlighted_block(None) self.mouse_pressed = False self.inventory_list.toggle() elif symbol == G.SOUND_UP_KEY: G.EFFECT_VOLUME = min(G.EFFECT_VOLUME + .1, 1) elif symbol == G.SOUND_DOWN_KEY: G.EFFECT_VOLUME = max(G.EFFECT_VOLUME - .1, 0) elif symbol == G.SCREENCAP_KEY: # dedicated screencap key now = datetime.datetime.now() dt = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute, now.second) st = dt.strftime('%Y-%m-%d_%H.%M.%S') filename = str(st) + '.png' if not os.path.exists('screencaptures'): os.makedirs('screencaptures') path = 'screencaptures/' + filename pyglet.image.get_buffer_manager().get_color_buffer().save(path) elif symbol == G.SHOWMAP_KEY: self.show_map() self.last_key = symbol def on_key_release(self, symbol, modifiers): if symbol == G.TALK_KEY: self.toggle_text_input() return pyglet.event.EVENT_HANDLED def on_resize(self, width, height): if G.HUD_ENABLED: self.label.y = height - 10 self.text_input.resize(x=0, y=0, width=self.window.width) self.chat_box.resize(x=0, y=self.text_input.y + self.text_input.height + 50, width=self.window.width / 2, height=min(300, self.window.height/3)) #self.debug_text.resize(0, self.window.height - 300, # 500, 300) def set_3d(self): width, height = self.window.get_size() glEnable(GL_DEPTH_TEST) glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(G.FOV, width / float(height), G.NEAR_CLIP_DISTANCE, G.FAR_CLIP_DISTANCE) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glPushMatrix() self.camera.look() self.skydome.draw() glPopMatrix() self.camera.transform() def clear(self): glClearColor(self.bg_red, self.bg_green, self.bg_blue, 1.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) def on_draw(self): self.clear() #self.window.clear() self.set_3d() #glColor3d(1, 1, 1) self.world.batch.draw() self.world.transparency_batch.draw() glEnable(GL_BLEND) glBlendFunc(GL_ZERO, GL_DST_ALPHA) self.crack_batch.draw() glDisable(GL_BLEND) self.draw_focused_block() for ply in self.player_ids.itervalues(): ply.model.draw() self.set_2d() if G.HUD_ENABLED: self.draw_label() self.item_list.draw() self.inventory_list.draw() #if G.DEBUG_TEXT_ENABLED: # self.update_label() #self.debug_text.draw() self.text_input.draw() glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) self.chat_box.draw() glDisable(GL_BLEND) def show_cracks(self, hit_block, vertex_data): if self.block_damage: # also show the cracks crack_level = int(CRACK_LEVELS * self.block_damage / hit_block.hardness) # range: [0, CRACK_LEVELS[ if crack_level >= CRACK_LEVELS: return texture_data = crack_textures.texture_data[crack_level] count = len(texture_data) / 2 if self.crack: self.crack.delete() self.crack = self.crack_batch.add(count, GL_QUADS, crack_textures.group, ('v3f/static', vertex_data), ('t2f/static', texture_data)) def draw_focused_block(self): glDisable(GL_LIGHTING) vector = self.player.get_sight_vector() position = self.world.hit_test(self.player.position, vector, self.player.attack_range)[0] if position: hit_block = self.world[position] if hit_block.density >= 1: self.focus_block.width = hit_block.width * 1.05 self.focus_block.height = hit_block.height * 1.05 vertex_data = self.focus_block.get_vertices(*position) if hit_block.hardness > 0.0: self.show_cracks(hit_block, vertex_data) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glColor4f(0.0, 0.0, 0.0, 0.4) glLineWidth(2.0) glDisable(GL_TEXTURE_2D) glDepthMask(False) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) pyglet.graphics.draw(24, GL_QUADS, ('v3f/static', vertex_data)) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glDepthMask(True) glEnable(GL_TEXTURE_2D) glDisable(GL_BLEND) def draw_label(self): x, y, z = self.player.position self.label.text = 'Time:%.1f Inaccurate FPS:%02d (%.2f, %.2f, %.2f) Blocks Shown: %d / %d sector_packets:%d'\ % (self.time_of_day if (self.time_of_day < 12.0) else (24.0 - self.time_of_day), pyglet.clock.get_fps(), x, y, z, len(self.world._shown), len(self.world), len(self.world.sector_packets)) self.label.draw() def update_label(self): x, y, z = self.player.position self.debug_text.clear() self.debug_text.write_line(' '.join((G.APP_NAME, str(G.APP_VERSION)))) self.debug_text.write_line('Time:%.1f Inaccurate FPS:%02d Blocks Shown: %d / %d sector_packets:%d'\ % (self.time_of_day if (self.time_of_day < 12.0) else (24.0 - self.time_of_day), pyglet.clock.get_fps(), len(self.world._shown), len(self.world), len(self.world.sector_packets))) self.debug_text.write_line('x: %.2f, sector: %d' %(x, x // G.SECTOR_SIZE)) self.debug_text.write_line('y: %.2f, sector: %d' %(y, y // G.SECTOR_SIZE)) self.debug_text.write_line('z: %.2f, sector: %d' %(z, z // G.SECTOR_SIZE)) #dirs = ['East', 'South', 'West', 'North'] #vec, direction, angle = self.player.get_sight_direction() #dx, dy, dz = vec #self.debug_text.write_line('Direction: (%.2f, %.2f, %.2f) %d(%s) %.2f' % (dx, dy, dz, direction, dirs[direction], angle)) def write_line(self, text, **kwargs): self.chat_box.write_line(text, **kwargs) def text_input_callback(self, symbol, modifier): if symbol == G.VALIDATE_KEY: txt = self.text_input.text.replace('\n', '') self.text_input.clear() if txt: self.world.packetreceiver.send_chat(txt) return pyglet.event.EVENT_HANDLED def hide_chat_box(self, dt): self.chat_box.toggle(False) def on_text_input_toggled(self): pyglet.clock.unschedule(self.hide_chat_box) # Disable the fade timer self.chat_box.toggle(state=self.text_input.visible) # Pass through the state incase chat_box was already visible if self.chat_box.visible: self.chat_box.focused = True # Allow scrolling self.window.push_handlers(self.chat_box) else: self.chat_box.focused = False self.window.remove_handlers(self.chat_box) def toggle_text_input(self): self.text_input.toggle() if self.text_input.visible: self.player.velocity = 0 self.player.strafe = [0, 0] self.window.push_handlers(self.text_input) self.text_input.focus() else: self.window.remove_handlers(self.text_input) def push_handlers(self): if self.setup(): self.window.push_handlers(self.camera) self.window.push_handlers(self.player) self.window.push_handlers(self) self.window.push_handlers(self.item_list) self.window.push_handlers(self.inventory_list) else: self.switch_controller_class(MainMenuController) def pop_handlers(self): while self.window._event_stack: self.window.pop_handlers() def on_close(self): G.save_config() self.world.packetreceiver.stop() # Disconnect from the server so the process can close def show_map(self): print("map called...") # taken from Nebual's biome_explorer, this is ment to be a full screen map that uses mini tiles to make a full 2d map. with open(os.path.join(G.game_dir, "world", "seed"), "rb") as f: SEED = f.read() b = BiomeGenerator(SEED) x, y, z = self.player.position curx = x cury = y xsize = 79 ysize = 28 pbatch = pyglet.graphics.Batch() pgroup = pyglet.graphics.OrderedGroup(1) DESERT, PLAINS, MOUNTAINS, SNOW, FOREST = range(5) letters = ["D","P","M","S","F"] # temp background pic... image = load_image('resources', 'textures', 'main_menu_background.png') #map_frame = image_sprite(image, pbatch, 0, y=G.WINDOW_WIDTH, height=G.WINDOW_HEIGHT) #sprite = pyglet.sprite.Sprite(image) #sprite.image(image) #sprite.visible = True # map_frame.draw() # map_frame.visible = True for y in range(int(cury),int(cury+ysize)): for x in range(int(curx),int(curx+xsize)): #string += letters[b.get_biome_type(x,y)] tmap = letters[b.get_biome_type(x,y)] tile_map = load_image('resources', 'textures', tmap +'.png') tile_map.anchor_x = x * 8 tile_map.anchor_Y = y * 8 sprite = pyglet.sprite.Sprite(tile_map, x=x * 8, y=y * 8, batch=pbatch) game_map = image_sprite(tile_map, pbatch, pgroup, x * 8, y * 8, 8, 8) game_map = pyglet.sprite.Sprite(image,x=G.WINDOW_WIDTH, y=G.WINDOW_HEIGHT,batch=pbatch, group=pgroup) game_map = pyglet.sprite.Sprite(tile_map,x=x*8, y=y*8,batch=pbatch, group=pgroup) tile_map.blit(x *8, y * 8) #tile_map.draw() #map.append(tmap) game_map.draw() pbatch.draw()
class OptionsView(MenuView): def setup(self): MenuView.setup(self) width, height = self.controller.window.width, self.controller.window.height self.layout = VerticalLayout(0, 0) textures_enabled = len(G.texture_pack_list.available_texture_packs) > 1 self.text_input = TextWidget(self.controller.window, G.USERNAME, 0, 0, width=160, height=20, font_name='Arial', batch=self.batch) self.controller.window.push_handlers(self.text_input) self.text_input.focus() self.text_input.caret.mark = len( self.text_input.document.text) # Don't select the whole text def text_input_callback(symbol, modifier): G.USERNAME = self.text_input.text self.text_input.push_handlers(key_released=text_input_callback) hl = HorizontalLayout(0, 0) sb = self.Scrollbar(x=0, y=0, width=300, height=40, sb_width=20, sb_height=40, caption="Music") hl.add(sb) def change_sound_volume(pos): G.EFFECT_VOLUME = float(float(pos) / 100) sb = self.Scrollbar(x=0, y=0, width=300, height=40, sb_width=20, sb_height=40, caption="Sound", pos=int(G.EFFECT_VOLUME * 100), on_pos_change=change_sound_volume) hl.add(sb) self.layout.add(hl) hl = HorizontalLayout(0, 0) button = self.Button(width=300, caption=G._("Controls..."), on_click=self.controller.controls) hl.add(button) self.buttons.append(button) button = self.Button(width=300, caption=G._("Textures"), on_click=self.controller.textures, enabled=textures_enabled) hl.add(button) self.buttons.append(button) self.layout.add(hl) button = self.ToggleButton( width=610, caption="Anti-aliasing/multisampling (need restart to take effect)", on_toggle=self.multisampling_callback) self.button = button self.button.enable(G.MULTISAMPLING) # TODO: Multisampling not working self.layout.add(button) self.buttons.append(button) button = self.Button(width=610, caption=G._("Done"), on_click=self.controller.main_menu) self.layout.add(button) self.buttons.append(button) self.label = Label('Options', font_name='ChunkFive Roman', font_size=25, x=width // 2, y=self.frame.y + self.frame.height, anchor_x='center', anchor_y='top', color=(255, 255, 255, 255), batch=self.batch, group=self.labels_group) self.on_resize(width, height) def on_resize(self, width, height): MenuView.on_resize(self, width, height) self.text_input.resize( x=self.frame.x + (self.frame.width - self.text_input.width) // 2 + 5, y=self.frame.y + self.frame.height // 2 + 75, width=150) def multisampling_callback(self): G.MULTISAMPLING = self.button.toggled G.config.set("Multisampling", "multisampling", str(self.button.toggled)) G.save_config()