Created
January 22, 2017 14:19
-
-
Save spinningD20/577e8d311cbaeead5c8b11c407862a47 to your computer and use it in GitHub Desktop.
tilemap seams with camera movement and scaling
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import defaultdict | |
import tmx | |
from cymunk.cymunk import Vec2d | |
from kivent_maps.map_utils import _load_obj_models, _load_tile_map, _load_tile_properties, parse_tmx | |
from kivent_maps.map_utils import _load_tilesets | |
from kivy.app import App, platform | |
from kivy.core.window import Window, Keyboard | |
from kivy.clock import Clock | |
from kivy.uix.widget import Widget | |
from kivy.properties import StringProperty | |
from kivent_core.managers.resource_managers import texture_manager | |
from os.path import dirname, join, abspath, basename | |
from kivent_maps import map_utils | |
import kivent_cymunk | |
from kivent_maps.map_system import MapSystem | |
Window.size = (1600, 900) | |
def get_asset_path(asset, asset_loc): | |
return join(dirname(dirname(abspath(__file__))), asset_loc, asset) | |
keys = defaultdict(lambda: False) | |
texture_manager.load_atlas(join(dirname(dirname(abspath(__file__))), 'assets', | |
'background_objects.atlas')) | |
class Game(Widget): | |
def __init__(self, **kwargs): | |
super(Game, self).__init__(**kwargs) | |
map_render_args = {'zones': ['general'], 'frame_count': 2, 'gameview': 'camera1', | |
'shader_source': get_asset_path('positionshader.glsl', 'assets/glsl')} | |
map_anim_args = {'zones': ['general'], } | |
map_poly_args = {'zones': ['general'], 'frame_count': 2, 'gameview': 'camera1', | |
'shader_source': 'poscolorshader.glsl'} | |
self.map_layers, self.map_layer_animators = map_utils.load_map_systems( | |
4, self.gameworld, map_render_args, map_anim_args, map_poly_args) | |
self.moving = False | |
self.gameworld.init_gameworld( | |
['cymunk_physics', 'position', 'color', 'camera1', 'tile_map'] | |
+ self.map_layers + self.map_layer_animators, callback=self.init_game) | |
def init_game(self): | |
self.move_to = None | |
self.setup_states() | |
self.set_state() | |
self.setup_tile_map() | |
self.add_player() | |
self.camera1.render_system_order = reversed(self.map_layers) | |
self.camera1.entity_to_focus = self.player_id | |
self.camera1.focus_entity = True | |
Clock.schedule_interval(self.update, 1 / 60) | |
def add_player(self): | |
pos = self.current_map.get_tile_position(*self.player_tile) | |
print('starting position', pos) | |
renderer_name = 'map_layer%d' % self.current_map.z_index_map[1] | |
shape_dict = {'inner_radius': 0, 'outer_radius': 0, 'mass': 0, 'offset': (0, 0)} | |
col_shape = {'shape_type': 'circle', 'elasticity': .5, 'collision_type': 1, 'shape_info': shape_dict, | |
'friction': 1.0} | |
col_shapes = [col_shape] | |
physics_component = {'main_shape': 'circle', | |
'velocity': (0, 0), 'position': pos, 'angle': 0, | |
'angular_velocity': 0, 'vel_limit': 0, | |
'ang_vel_limit': 0, 'mass': 0, 'col_shapes': col_shapes} | |
component_data = {'position': pos, | |
renderer_name: {'model': 'star2', 'texture': 'star2', 'size': [20, 20]}, | |
'rotate': 0, | |
'cymunk_physics': physics_component} | |
systems = ['position', renderer_name, 'rotate', 'cymunk_physics'] | |
self.player_id = self.gameworld.init_entity(component_data, systems) | |
self.player = self.gameworld.entities[self.player_id] | |
def setup_tile_map(self): | |
filename = get_asset_path('orthogonal.tmx', 'assets/maps/') | |
map_manager = self.gameworld.managers['map_manager'] | |
map_name = parse_tmx(filename, self.gameworld) | |
map_utils.init_entities_from_map(map_manager.maps[map_name], self.gameworld.init_entity) | |
self.current_map = map_manager.maps[map_name] | |
# print(self.current_map.width) | |
self.player_tile = (0, 0) | |
print(self.current_map.size) | |
def on_touch_up(self, touch): | |
print(self.camera1.convert_from_screen_to_world(touch.pos)) | |
def setup_states(self): | |
self.gameworld.add_state(state_name='main', systems_added=self.map_layers, | |
systems_unpaused=self.map_layer_animators + self.map_layers) | |
def set_state(self): | |
self.gameworld.state = 'main' | |
def update(self, dt): | |
direction = None | |
if keys.get(Keyboard.keycodes['right']): | |
direction = (1, 0) | |
keys[Keyboard.keycodes['right']] = False | |
elif keys.get(Keyboard.keycodes['down']): | |
direction = (0, 1) | |
keys[Keyboard.keycodes['down']] = False | |
elif keys.get(Keyboard.keycodes['left']): | |
direction = (-1, 0) | |
keys[Keyboard.keycodes['left']] = False | |
elif keys.get(Keyboard.keycodes['up']): | |
direction = (0, -1) | |
keys[Keyboard.keycodes['up']] = False | |
if direction: | |
x = direction[0] + self.player_tile[0] | |
y = direction[1] + self.player_tile[1] | |
go = True | |
go = False if (x < 0 or y < 0) else go | |
go = False if (x > self.current_map.size[0]-1 or y > self.current_map.size[1]-1) else go | |
go = False if (x == self.player_tile[0] and y == self.player_tile[1]) else go | |
if go: | |
print('moving from', self.player_tile) | |
entity = self.gameworld.entities[self.player_id] | |
coords = self.current_map.get_tile_position(x, y) | |
self.player_tile = (x, y) | |
print('moving to', coords, self.player_tile) | |
entity.cymunk_physics.body.position = Vec2d(coords) | |
else: | |
print('too far or same tile', x, y) | |
self.gameworld.update(dt) | |
class DebugPanel(Widget): | |
fps = StringProperty(None) | |
def __init__(self, **kwargs): | |
super(DebugPanel, self).__init__(**kwargs) | |
Clock.schedule_once(self.update_fps) | |
def update_fps(self, dt): | |
self.fps = str(int(Clock.get_fps())) | |
Clock.schedule_once(self.update_fps, .1) | |
class YourAppNameApp(App): | |
pass | |
if __name__ == '__main__': | |
if platform != 'android': | |
def on_key_down(window, keycode, *rest): | |
keys[keycode] = True | |
def on_key_up(window, keycode, *rest): | |
keys[keycode] = False | |
Window.bind(on_key_down=on_key_down, on_key_up=on_key_up) | |
YourAppNameApp().run() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#:kivy 1.9.0 | |
#:import get_asset_path __main__.get_asset_path | |
#:set map_layers ['map_layer%d' % i for i in range(4)] | |
#:import path os.path | |
#:import dirname os.path.dirname | |
#:import main __main__ | |
Game: | |
<Game>: | |
gameworld: gameworld | |
camera1: camera1 | |
GameWorld: | |
id: gameworld | |
gamescreenmanager: gamescreenmanager | |
size_of_gameworld: 400000 | |
system_count: 7 | |
zones: {'general': 100000} | |
PositionSystem2D: | |
system_id: 'position' | |
gameworld: gameworld | |
zones: ['general'] | |
RotateSystem2D: | |
system_id: 'rotate' | |
gameworld: gameworld | |
zones: ['general'] | |
RotateRenderer: | |
gameworld: gameworld | |
zones: ['general'] | |
shader_source: path.join(dirname(dirname(path.abspath(main.__file__))), 'assets', 'glsl', 'positionrotateshader.glsl') | |
CymunkPhysics: | |
system_id: 'cymunk_physics' | |
gameworld: gameworld | |
zones: ['general'] | |
ColorSystem: | |
system_id: 'color' | |
gameworld: gameworld | |
zones: ['general'] | |
GameView: | |
system_id: 'camera1' | |
gameworld: gameworld | |
window_size: root.size | |
size_hint: None, None | |
size: self.window_size | |
# change this to .5 or etc to see scaling seams | |
camera_scale: 1 | |
pos: root.pos | |
do_scroll_lock: False | |
id: camera1 | |
updateable: True | |
MapSystem: | |
system_id: 'tile_map' | |
id: tile_map | |
gameworld: gameworld | |
zones: ['general'] | |
GameScreenManager: | |
id: gamescreenmanager | |
size: root.size | |
pos: root.pos | |
gameworld: gameworld | |
<GameScreenManager>: | |
MainScreen: | |
id: main_screen | |
<MainScreen@GameScreen>: | |
name: 'main' | |
FloatLayout: | |
DebugPanel: | |
size_hint: (.2, .1) | |
pos_hint: {'x': .225, 'y': .025} | |
<DebugPanel>: | |
Label: | |
pos: root.pos | |
size: root.size | |
font_size: root.size[1]*.5 | |
halign: 'center' | |
valign: 'middle' | |
color: (1,1,1,1) | |
text: 'FPS: ' + root.fps if root.fps != None else 'FPS:' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment