Skip to content
Snippets Groups Projects
Select Git revision
  • 1b11c972de1f8fdda10051235212fbd89f9be7f7
  • 2023ss default protected
  • 2022ss
  • 2021ss
  • 2020ss
  • 2019ss
  • 2018ss
  • 2017ss
  • 2016ss
  • 2015ss
  • 2014ss
11 results

test.txt

Blame
  • Forked from Peter Gerwinski / bs
    Source project has a limited visibility.
    Main.gd 15.05 KiB
    extends Node
    
    # The port we will listen to.
    var port = 0
    # Our WebSocketServer instance.
    var _server = WebSocketServer.new()
    var player_one_client_id
    var player_two_client_id
    
    
    
    var action_player_one =  InputEventAction.new()
    var next_step_player_one = false
    var action_trainer_one = ""
    
    var action_player_two =  InputEventAction.new()
    var next_step_player_two = false
    var action_trainer_two = ""
    
    var Ball = preload("Ball.tscn")
    var ball = Ball.instance()
    var score_player_one = 0
    var score_player_two = 0
    var reward_player_one=0
    var reward_player_two=0
    
    var playing = false
    var score_event = false
    var game_done = false
    
    const SPACE_TO_PLAY = "Press SPACE to Play!"
    const P1_WIN = "Player 1 won!"
    const P2_WIN = "Player 2 won!"
    var message = SPACE_TO_PLAY
    
    var enable_rendering = true
    var learn_with_images = true
    var game_playtime_per_step = 0.1
    var max_wins = 21
    
    func _ready():
        enable_rendering = $"/root/GameSettings".rendering_enabled
        learn_with_images = $"/root/GameSettings".learn_with_images
        game_playtime_per_step = $"/root/GameSettings".game_playtime_per_step
        max_wins = $"/root/GameSettings".game_wins_to_reset
        port =  $"/root/GameSettings".game_port
        if not enable_rendering:
            VisualServer.render_loop_enabled = false # disable rendering to create a massive boost
        if learn_with_images:
            $DisplayMessage.hide()
            $Player1Score.hide()
            $Player2Score.hide()
        
        # Connect base signals to get notified of new client connections,
        # disconnections, and disconnect requests.
        _server.connect("client_connected", self, "_connected")
        _server.connect("client_disconnected", self, "_disconnected")
        _server.connect("client_close_request", self, "_close_request")
        # This signal is emitted when not using the Multiplayer API every time a
        # full packet is received.
        # Alternatively, you could check get_peer(PEER_ID).get_available_packets()
        # in a loop for each connected peer.
        _server.connect("data_received", self, "_on_data")
        # Start listening on the given port.
        var server_err = _server.listen(port)
        if server_err != OK:
            print("Unable to start server")
            set_process(false)
    
        set_ball()
        $PlayerOne.start($StartPositionPlayerOne.position)
        $PlayerTwo.start($StartPositionPlayerTwo.position)
        display_message()
        update_score()
        pause()
    
    
    func _input(_event):
        if Input.is_key_pressed(KEY_SPACE):
            play()
    
    func play():
        if game_done: # if game was done, reset states to start a fresh game
            game_done = false
            score_player_one = 0
            score_player_two = 0
            message = SPACE_TO_PLAY
            update_score()    
        playing = true
        ball.set_playing(playing)
        $DisplayMessage.visible = false
    
    
    func _process(delta):
        # Call this in _process or _physics_process.
        # Data transfer, and signals emission will only happen when calling this function.
        _server.poll()
            
        check_point_scored()
        handle_score_event()
        handle_game_end()
        
    func check_point_scored():
        if ball.position.x <= 0:
            score_event = true
            score_player_two += 1
            reward_player_one=(-1)
            reward_player_two=1
            print("player two won")
        if ball.position.x >= 1024:
            score_event = true
            score_player_one += 1
            reward_player_one=1
            reward_player_two=(-1)
            print("player one won")
        update_score()
        if score_player_one == 5 or score_player_two == 5:
            game_done = true
    
    func handle_score_event():
        if score_event:
            remove_ball()
            set_ball()
            reset_paddle_positions()
            display_message()
            playing = false
            score_event = false
    
        
    func update_score():
        $Player1Score.text = str(score_player_one)
        $Player2Score.text = str(score_player_two)
    
    func display_message():
        $DisplayMessage.text = message
        $DisplayMessage.visible = true
        
    
    func new_game():
        score_player_one = 0
        score_player_two = 0
        reward_player_one = 0
        reward_player_two = 0
        $PlayerOne.start($StartPositionPlayerOne.position)
        $PlayerTwo.start($StartPositionPlayerTwo.position)
        $StartTimer.start()
    
    func remove_ball():
        remove_child(ball)
    
    func set_ball():
        ball = Ball.instance()
        add_child(ball)
        ball.start($StartPositionBall.position)
    
    func reset_paddle_positions():
        $PlayerOne.start($StartPositionPlayerOne.position)
        $PlayerTwo.start($StartPositionPlayerTwo.position)
    
    func handle_game_end():
        if game_done:
            if score_player_one >= max_wins:
                message = P1_WIN
            else:
                message = P2_WIN
            display_message()
    
    
    
    
    func _on_PlayerTwo_hit():
        ball.ball_hit_paddle($PlayerTwo.position, $PlayerTwo/CollisionShape2D.shape.extents, false)
        pass # Replace with function body.
    
    
    func _on_PlayerOne_hit():
        ball.ball_hit_paddle($PlayerOne.position, $PlayerOne/CollisionShape2D.shape.extents, true)
        pass # Replace with function body.
    
    
    func _connected(id, proto):
        # This is called when a new peer connects, "id" will be the assigned peer id,
        # "proto" will be the selected WebSocket sub-protocol (which is optional)
        #print("Client %d connected with protocol: %s" % [id, proto])
        pass
    
    func _close_request(id, code, reason):
        # This is called when a client notifies that it wishes to close the connection,
        # providing a reason string and close code.
        #print("Client %d disconnecting with code: %d, reason: %s" % [id, code, reason])
        pass
    
    func _disconnected(id, was_clean = false):
        # This is called when a client disconnects, "id" will be the one of the
        # disconnecting client, "was_clean" will tell you if the disconnection
        # was correctly notified by the remote peer before closing the socket.
        if( player_one_client_id == id ):
            player_one_client_id = null
            #print("Player One with Client %d disconnected, clean: %s" % [id, str(was_clean)])
        if(player_two_client_id == id):
            player_two_client_id = null
    
    func _on_data(id):
        
       # Print the received packet, you MUST always use get_peer(id).get_packet to receive data,
        # and not get_packet directly when not using the MultiplayerAPI.
        var pkt = _server.get_peer(id).get_packet()
        #print("Got data from client %d: %s ... echoing" % [id, pkt.get_string_from_utf8()])
        
        var data = (JSON.parse(pkt.get_string_from_utf8())).get_result()
        print(data)
        if(data):
            for i in data:
                #print(i)
                if(i=="player_one"):
                    player_one_client_id = id
                if(i=="player_two"):
                    player_two_client_id = id
                if(i == "player_one_up"):
                    action_player_one = InputEventAction.new()
                    action_player_one.action = i
                    action_player_one.pressed = true
                    Input.parse_input_event(action_player_one)
                    next_step_player_one  = true
                if(i == "player_one_down"):
                    action_player_one = InputEventAction.new()
                    action_player_one.action = i
                    action_player_one.pressed = true
                    Input.parse_input_event(action_player_one)
                    next_step_player_one  = true
                if(i=="player_one_nothing"):
                    next_step_player_one  = true
                if(i == "player_two_up"):
                    action_player_two = InputEventAction.new()
                    action_player_two.action = i
                    action_player_two.pressed = true
                    Input.parse_input_event(action_player_two)
                    next_step_player_two  = true
                if(i == "player_two_down"):
                    action_player_two = InputEventAction.new()
                    action_player_two.action = i
                    action_player_two.pressed = true
                    Input.parse_input_event(action_player_two)
                    next_step_player_two  = true
                if(i == "player_two_nothing"):
                    next_step_player_two  = true
                if(i=="connect_player" or i == "start_game"):
                    if(i == "start_game"):
                        play()
                    var return_value = null
                    if learn_with_images:
                        return_value = yield(get_yielded_return_value(), "completed")
                    else:
                        return_value = get_return_value()
                        
                    if (player_one_client_id != null) and (player_one_client_id == id):    
                        _server.get_peer(id).put_packet((JSON.print(return_value['player_one'])).to_utf8())
                    elif player_two_client_id != null and player_two_client_id == id:
                        _server.get_peer(id).put_packet((JSON.print(return_value['player_two'])).to_utf8())
                    else:
                        _server.get_peer(id).put_packet((JSON.print(return_value)).to_utf8()) # Fallback, if the id is unknown
                    pass
                    
                if($"/root/GameSettings".trainings_mode_enabled):
                    if(i=="player_one_training"):
                        next_step_player_one = true
                        # is w pressed => up
                        #elif is s pressed => down
                        # else => nothing
                        if(Input.is_action_pressed("player_one_up")):
                            action_trainer_one = "up"
                        elif Input.is_action_pressed("player_one_down"):
                            action_trainer_one = "down"
                        else:
                            action_trainer_one = "nothing"
                    if(i=="player_two_training"):
                        next_step_player_two = true
                        # is arrow_up pressed => up
                        #elif is arrow_down pressed => down
                        # else => nothing          
                        if(Input.is_action_pressed("player_two_up")):
                            action_trainer_two = "up"
                        elif Input.is_action_pressed("player_two_down"):
                            action_trainer_two = "down"
                        else:
                            action_trainer_two = "nothing"          
                            
        if(next_step_player_one and next_step_player_two):
            if($"/root/GameSettings".trainings_mode_enabled and $"/root/GameSettings".trainer_realtime_enabled):
                yield(get_tree().create_timer(game_playtime_per_step), "timeout")
            unpause()
            $PlayerOne.run(game_playtime_per_step)
            $PlayerTwo.run(game_playtime_per_step)
            ball.run(game_playtime_per_step)
            timeout()
        
            
    func get_observation():
        var ball_observation=ball.get_observation()
        var player_one = {"PlayerOne":{"X":$PlayerOne.position.x,"Y":$PlayerOne.position.y, "TrainingAction":action_trainer_one}, "PlayerTwo":{"X":$PlayerTwo.position.x,"Y":$PlayerTwo.position.y, "TrainingAction":action_trainer_two}, "ball":ball_observation['player_one']}
        var player_two = {"PlayerOne":{"X":abs($PlayerTwo.position.x - $"/root/GameSettings".display_window_width),"Y":$PlayerTwo.position.y, "TrainingAction":action_trainer_two}, "PlayerTwo":{"X":abs($PlayerOne.position.x- $"/root/GameSettings".display_window_width),"Y":$PlayerOne.position.y, "TrainingAction":action_trainer_one}, "ball":ball_observation['player_two']}
        return {"player_one":player_one, "player_two":player_two}
            
    func get_return_value():
        var observation = get_observation()
        var return_value_player_one = {"observation":observation['player_one'], "reward":{"PlayerOne":reward_player_one, "PlayerTwo":reward_player_two}, "done":(not playing), "info":{"PlayerOneScore":score_player_one, "PlayerTwoScore":score_player_two}}
        var return_value_player_two = {"observation":observation['player_two'], "reward":{"PlayerOne":reward_player_two, "PlayerTwo":reward_player_one}, "done":(not playing), "info":{"PlayerOneScore":score_player_two, "PlayerTwoScore":score_player_one}}
        return {'player_one':return_value_player_one, 'player_two':return_value_player_two}
    
    func get_yielded_return_value():
        var observation = get_observation()
        var screenshot = yield(get_screenshot(), "completed")
    
        var return_value_player_one = {"observation":observation['player_one'], "reward":{"PlayerOne":reward_player_one, "PlayerTwo":reward_player_two}, "done":(not playing), "info":{"PlayerOneScore":score_player_one, "PlayerTwoScore":score_player_two, "screenshot":screenshot['player_one']}}
        var return_value_player_two = {"observation":observation['player_two'], "reward":{"PlayerOne":reward_player_two, "PlayerTwo":reward_player_one}, "done":(not playing), "info":{"PlayerOneScore":score_player_two, "PlayerTwoScore":score_player_one, "screenshot":screenshot['player_two']}}
        return {'player_one':return_value_player_one, 'player_two':return_value_player_two}
    
    func get_screenshot():
        get_viewport().set_clear_mode(Viewport.CLEAR_MODE_ONLY_NEXT_FRAME)
        # Wait until the frame has finished before getting the texture.
        yield(VisualServer, "frame_post_draw")
    
        var thumbnail = get_viewport().get_texture().get_data()
        thumbnail.flip_y()    
        thumbnail.resize(100, 60 )
        if $"/root/GameSettings".image_rgb: 
            thumbnail.convert(Image.FORMAT_RGB8 ) # Farbe
        else:
            thumbnail.convert(Image.FORMAT_L8 ) # S/W
        
        #thumbnail.save_png('test.png') # Save Image as file - to debug
    
        var sg_width = thumbnail.get_width()
        var sg_height = thumbnail.get_height()
        var sg_format = thumbnail.get_format()
        
        var array_player_one : PoolByteArray = thumbnail.get_data()
        var sg_saved_img_player_one = Marshalls.raw_to_base64(array_player_one)
        var sg_u_size_player_one = array_player_one.size()
        var screenshot_player_one = {"image" : sg_saved_img_player_one, "size" : sg_u_size_player_one, "width" : sg_width, "height" : sg_height, "format" : sg_format}
        
        thumbnail.flip_x()
        var array_player_two : PoolByteArray = thumbnail.get_data()
        var sg_saved_img_player_two = Marshalls.raw_to_base64(array_player_two)
        var sg_u_size_player_two = array_player_two.size()
        var screenshot_player_two = {"image" : sg_saved_img_player_one, "size" : sg_u_size_player_two, "width" : sg_width, "height" : sg_height, "format" : sg_format}
        
        
        return {"player_one":screenshot_player_one, "player_two":screenshot_player_two}
    
    
    func timeout():
        pause()  
        action_player_one.pressed = false
        action_player_two.pressed = false
        Input.parse_input_event(action_player_one)
        Input.parse_input_event(action_player_two)
        next_step_player_one = false
        next_step_player_two = false
        
        var return_value = null
        if learn_with_images:
            return_value = yield(get_yielded_return_value(), "completed")
        else:
            return_value = get_return_value()
            
        reward_player_one = 0
        reward_player_two = 0
        ##print(return_value)
        if(player_one_client_id):
            _server.get_peer(player_one_client_id).put_packet((JSON.print(return_value['player_one'])).to_utf8())
        if(player_two_client_id):
            _server.get_peer(player_two_client_id).put_packet((JSON.print(return_value['player_two'])).to_utf8())
    
        
    func pause():
        #print("pause")
        ball.set_pause(true)
        $PlayerOne.set_pause(true)
        $PlayerTwo.set_pause(true)
        
    func unpause():
        #print("unpause")
        ball.set_pause(false)
        $PlayerOne.set_pause(false)
        $PlayerTwo.set_pause(false)