from kivy.app import App from kivy.core.window import Window from kivy.uix.floatlayout import FloatLayout from kivy.uix.label import Label from kivy.clock import Clock from kivy.uix.progressbar import ProgressBar from kivy.lang import Builder from starfield import Starfield from kivy.uix.image import Image from kivy.properties import NumericProperty, StringProperty from math import sin, cos, radians from PodSixNet.Connection import connection from PodSixNet.Connection import ConnectionListener Builder.load_file('spacegame.kv') FPS = 30 DEBUG = False HOST = 'scclassroom.com' #HOST = '127.0.0.1' PORT = 34002 class SpaceGame(FloatLayout, ConnectionListener): def __init__(self): FloatLayout.__init__(self) self._keyboard = Window.request_keyboard(self._keyboard_closed, self) self._keyboard.bind(on_key_down = self._on_keyboard_down) self._keyboard.bind(on_key_up = self._on_keyboard_up) self.controls = { 'thrust': 0, 'turning': 0, 'attack': 0, } self.old_controls = dict(self.controls) self.hud = FloatLayout(size_hint = (1, 1)) self.add_widget(self.hud) self.objects = {} self.space = FloatLayout() self.add_widget(self.space) health_label = Label(text='Health') health_label.pos_hint = {'top': 1.47} self.health = ProgressBar( pos_hint = {'top': 1, 'center_x': 0.5}, size_hint = (0.5, 0.1), max = 30, value = 30, ) self.hud.add_widget(self.health) self.player_id = None if DEBUG: data = { 'object_id': 1, 'type': 'planet', 'pos_x': 0, 'pos_y': 0, 'angle': 0, 'vel_x': 0, 'vel_y': 0, 'vel_angle': 0, } self.add_object(data) data = { 'object_id': 2, 'type': 'bullet', 'pos_x': 100, 'pos_y': 100, 'angle': 0, 'vel_x': -10, 'vel_y': -10, 'vel_angle': 45, } self.add_object(data) self.player_id = 1 data = { 'object_id': 1, 'type': 'player', 'pos_x': 50, 'pos_y': 50, 'angle': 180, 'vel_x': 10, 'vel_y': 10, 'vel_angle': 45, } self.add_object(data) self.accel = 50 self.angle = 0 self.old_angle = -1 self.max_speed = 150 self.max_x = 0 self.max_y = 0 self.hud.add_widget( health_label ) def update(self, delta_time): if DEBUG: player = self.objects[self.player_id] controls = self.controls turning = self.controls['turning'] accel = self.accel * delta_time angle = player.angle if turning == 1: player.vel_angle = -160 elif turning == 2: player.vel_angle = 160 else: player.vel_angle = 0 if self.old_angle != angle: self.old_angle = angle temp_vx = 0 temp_vy = 0 while abs(temp_vx) + abs(temp_vy) < self.max_speed: temp_vx += sin(radians(angle)) * accel temp_vy += cos(radians(angle)) * accel self.max_x = temp_vx self.max_y = temp_vy max_x = self.max_x max_y = self.max_y if controls['thrust'] == 1: future_x = player.vel_x + sin(radians(angle)) * accel future_y = player.vel_y + cos(radians(angle)) * accel if (future_y < max_y) if max_y > 0 else (future_y > max_y): player.vel_y = future_y if (future_x < max_x) if max_x > 0 else (future_x > max_x): player.vel_x = future_x if game.connected: self.send_action({'action': 'player'}) self.update_controls() self.Pump() for i in self.objects: obj = self.objects[i] obj.update(delta_time) if self.player_id: x = self.objects[self.player_id].true_pos[0] y = self.objects[self.player_id].true_pos[1] self.starfield.scroll(x, y, 0) def add_object(self,data): object_id = data['object_id'] if data['type'] == 'player': image = 'images/player.png' elif data['type'] == 'bullet': image = 'images/weapon.png' elif data['type'] == 'planet': image = 'images/planet.png' else: image = 'images/player.png' new_object = GenericObject(source = image) self.objects[object_id] = new_object self.update_object(data) self.space.add_widget(new_object) if self.player_id == object_id: self.new_player() def new_player(self): for object_id in self.objects: if self.player_id != object_id: self.objects[object_id].new_player(self.objects[self.player_id]) pass def remove_object(self, object_id): if object_id in self.objects: obj = self.objects[object_id] self.space.remove_widget(obj) del self.objects[object_id] del obj def update_controls(self): if self.controls != self.old_controls: self.old_controls = dict(self.controls) action = { 'action': 'controls', 'controls': self.old_controls, } self.send_action(action) def send_action(self, action): self.Send(action) def Network_update(self, data): for u in data['updates']: if u: self.update_object(u) def Network_player(self, data): if 'info' in data: if 'id' in data['info']: self.player_id = data['info']['id'] self.health.max = data['info']['max_health'] self.health.value = data['info']['health'] def Network_delete(self, data): self.remove_object(data['object_id']) def _keyboard_closed(self): self._keyboard.unbind(on_key_down = self._on_keyboard_down) self._keyboard = None def _on_keyboard_down(self, keyboard, keycode, text, modifiers): key = keycode[1] if key == 'a': self.controls['turning'] = 1 elif key == 'd': self.controls['turning'] = 2 elif key == 'w': self.controls['thrust'] = 1 if key == 'spacebar': self.controls['attack'] = 1 #print 'down', key def _on_keyboard_up(self, keyboard, keycode): key = keycode[1] if key == 'a' or key == 'd': self.controls['turning'] = 0 elif key == 'w': self.controls['thrust'] = 0 elif key == 'spacebar': self.controls['attack'] = 0 #print 'up', key def update_object(self,data): object_id = data['object_id'] if object_id not in self.objects: self.add_object(data) return self.objects[object_id].update_data(data) if self.player_id and self.player_id != object_id: player = self.objects[self.player_id] self.objects[object_id].new_player(player) class GenericObject(Image): angle = NumericProperty(120) source = StringProperty('images/player.png') vel_x = NumericProperty(0) vel_y = NumericProperty(0) vel_angle = NumericProperty(0) true_pos = (0,0) player = None def update_data(self, data): self.true_pos = (data['pos_x'], data['pos_y']) self.angle = data['angle'] self.vel_x = data['vel_x'] self.vel_y = data['vel_y'] self.vel_angle = data['vel_angle'] self.move() def update(self, delta_time): pos = self.true_pos angle = self.angle new_x = pos[0] + (self.vel_x * delta_time) new_y = pos[1] + (self.vel_y * delta_time) new_angle = angle + (self.vel_angle * delta_time) self.true_pos = (new_x, new_y) self.angle = new_angle self.move() def move(self): if self.player: new_x = (self.true_pos[0] - self.player.true_pos[0]) + (Window.width / 2.0) new_y = (self.true_pos[1] - self.player.true_pos[1]) + (Window.height / 2.0) self.center = (new_x, new_y) else: self.center = (Window.width / 2.0, Window.height / 2.0) def new_player(self,entity): self.player = entity class SpaceApp(App, ConnectionListener): def __init__(self): App.__init__(self) self.connected = False self.Connect((HOST, PORT)) def update(self, delta_time): connection.Pump() self.Pump() self.game.update(delta_time) def Network_connected(self, data): print 'Connected to the server!' self.connected = True def Network_disconnected(self, data): print 'Disconnected to the server!' self.connected = False def Network_error(self, data): print data def build(self): self.game = SpaceGame() Clock.schedule_interval(self.update, 1.0 / FPS) return self.game if __name__ == "__main__": game = SpaceApp() game.run()
Run
Reset
Share
Import
Link
Embed
Language▼
English
中文
Python Fiddle
Python Cloud IDE
Follow @python_fiddle
Browser Version Not Supported
Due to Python Fiddle's reliance on advanced JavaScript techniques, older browsers might have problems running it correctly. Please download the latest version of your favourite browser.
Chrome 10+
Firefox 4+
Safari 5+
IE 10+
Let me try anyway!
url:
Go
Python Snippet
Stackoverflow Question