• ETPH

    Hi everyone!

    This is my first post here, and the interface is kind of confusing, so I’m sorry if this is formatted strangely. I’ve been trying to teach myself how to code through this game. It’s a tile sliding game, trying to order the tiles into a correct position. Currently, I’m just trying to get movement to work, and the sprites and abilit to start/end/win a game haven’t been implemented. I’ve gotten most of it going, but I can’t seem to get the tiles to move around correctly.

    I want one of three things to happen: if the tile tries to move past the boundaries, it can’t move; if the tile tries to move onto another tile, it can’t move; if the tile tries to move to a free space, it moves. I’ve been trying to do this using a for loop (as the names of the tiles are stored under the same variable name, so I have to access them in a way other than by name). However, I can’t get the code to do those three things consistently. I’m pretty sure the problem is with the for loop and if statement combination I have, but I can’t think of another method for doing this.
    Sorry that some of the comments haven’t been updated as I’ve been changing the code, but most of it is still correct.

    I’m using an iPad Pro, version 11.2.2, and Pythonista version 3.2.

    Any help would be appreciated. Code starts after this line.

    '''Description: A 4x4 board of numbered tiles has one missing space and is randomly set up. To win the game, the player must slide tiles over to put the tiles back in order.

    Variants: Instead of numbers, you can have a scrambled picture cut up into 4x4 tiles.'''

    from scene import *
    import random
    import ui
    import marshal
    import string
    import sound
    import math
    import time
    import Image, ImageDraw

    class Game(Scene):

    MARGIN_OF_ERROR = 33
    
    #Creates background and initial variables that the rest of the game builds off of.
    def setup(self):
        self.background_color = '#646464' 
        self.create_tile()
        self.drag = False
        self.Tile = None
        self.touch_location = None
        self.touched_tile = None
        
        #Creates tiles and adds their graphics by randomly selecting a position (was supposed to have numbers but couldn't get that working), adds that position to actual_position list and removes it from position_options lists so no tile is put in the same spot. It then adds all those tiles the game generated into a list that gets accessed later in the game.
    def create_tile(self):
        position_options = [(522, 510), (522, 444), (522, 378), (522, 312), (588, 510), (588, 444), (588, 378),
                                                (588, 312), (654, 510), (654, 444), (654, 378), (654, 312), (456, 510), (456, 444),
                                                (456, 378)] #possible positions
        actual_position = []
        self.tiles = []
        t_shape = 'plf:Tile_BoxCrate' #sprite of tile
        for j in range(15):
            position = random.choice(position_options) #chooses position
            actual_position.append(position) #adds position to other list
            position_options.remove(position) #removes position so it can't be rechosen
            self.Tile = SpriteNode(t_shape, position) #creates tile
            self.tiles.append(self.Tile) #adds that tile to self.tiles list
            self.add_child(self.Tile) #adds tile to gameboard
    
    #this function determines where player has touched. It goes through every position option and compares the x and y value of where player touched to intial position option with a margin of error of twenty. It then adds that position to a self.drag variable to be used elsewhere in the class.
    def touch_began(self, touch):
        position_options = [(522, 510), (522, 444), (522, 378), (522, 312), (588, 510), (588, 444), (588, 378),
                                                (588, 312), (654, 510), (654, 444), (654, 378), (654, 312), (456, 510), (456, 444),
                                                (456, 378), (456, 312)]
        for j in position_options:
            if touch.location[0] <= j[0] + self.MARGIN_OF_ERROR and touch.location[0] >= j[0] - self.MARGIN_OF_ERROR and touch.location[1] <= j[1] + self.MARGIN_OF_ERROR and touch.location[1] >= j[1] - self.MARGIN_OF_ERROR:
                #checks if touch.location is within the margin of error to a position option
                self.drag = j #sets empty variable self.drag to that position
                            
    #this is the where the function checks if the touch has moved. It first loops through every position of the tiles previously generated and compares that to the self.drag position set earlier. It then sets the self.touched_tile variable to that tile SpriteNode created earlier, which will then allow movement. After that it checks where the player's touch ends and compares that to the inital self.drag position. Then based on that touch movement, it moved the SpriteNode to the next position over in that direction.
    def touch_moved(self, touch):
        for i in self.tiles: 
            if i.position == self.drag:
                self.touched_tile = i #checks to see if there is a tile at that position and sets it to the touched_tile variable
        if touch.location[0] - self.drag[0] >= 50 and touch.location[1] <= touch.location[1] + self.MARGIN_OF_ERROR and touch.location[1] >= touch.location[1] - self.MARGIN_OF_ERROR: #checks to see if touch movement moves right
            move_right = Action.move_to(self.drag[0] + 66, self.drag[1], 1, TIMING_SINODIAL) #sets how tile moves
            for j in self.tiles:
                if self.drag[0] + 66 > 680:
                    self.drag == False
                    self.touched_tile == None
                    print("Didn't move off gameboard")
                    return self.drag and self.touched_tile
                elif self.drag[0] + 66 != j.position[0] and self.drag[1] == j.position[1]:
                    self.touched_tile.run_action(move_right)
                    self.drag == False
                    print("I moved right")
                    return self.touched_tile and self.drag
                else:
                    self.drag == False
                    self.touched_tile == None
                    print("Failed")
                    return self.drag and self.touched_tile
        elif touch.location[0] - self.drag[0] <= -50 and touch.location[1] <= touch.location[1] + self.MARGIN_OF_ERROR and touch.location[1] >= touch.location[1] - self.MARGIN_OF_ERROR: #checks to see if touch movement moves left
            move_left = Action.move_to(self.drag[0] - 66, self.drag[1], 1, TIMING_SINODIAL)
            for j in self.tiles:
                if self.drag[0] - 66 < 440:
                    self.drag == False
                    self.touched_tile == None
                    print("Didn't move off gameboard")
                    return self.drag and self.touched_tile
                elif self.drag[0] - 66 != j.position[0] and self.drag[1] == j.position[1]:
                    self.touched_tile.run_action(move_left)
                    self.drag == False
                    print("I moved left")
                    return self.touched_tile and self.drag
                else:
                    self.drag == False
                    self.touched_tile == None
                    print("Failed")
                    return self.drag and self.touched_tile
        elif touch.location[1] - self.drag[1] >= 50 and touch.location[0] <= touch.location[0] + self.MARGIN_OF_ERROR and touch.location[0] >= touch.location[0] - self.MARGIN_OF_ERROR: #checks to see if touch movement moves up
            move_up = Action.move_to(self.drag[0], self.drag[1] + 66, 1, TIMING_SINODIAL)
            for j in self.tiles:
                if self.drag[1] + 66 > 530:
                    self.drag == False
                    self.touched_tile == None
                    print("Didn't move off gameboard")
                    return self.drag and self.touched_tile
                elif self.drag[1] + 66 != j.position[1] and self.drag[0] == j.position[0]:
                    self.touched_tile.run_action(move_up)
                    self.drag == False
                    print("I moved up")
                    return self.touched_tile and self.drag
                else:
                    self.drag == False
                    self.touched_tile == None
                    print("Failed")
                    return self.drag and self.touched_tile
        elif touch.location[1] - self.drag[1] <= -50 and touch.location[0] <= touch.location[0] + self.MARGIN_OF_ERROR and touch.location[0] >= touch.location[0] - self.MARGIN_OF_ERROR: #checks to see if touch movement moves down
            move_down = Action.move_to(self.drag[0], self.drag[1] - 66, 1, TIMING_SINODIAL)
            for j in self.tiles:
                if self.drag[1] - 66 < 300:
                    self.drag == False
                    self.touched_tile
                    print("Didn't move off gameboard")
                    return self.drag and self.touched_tile
                elif self.drag[1] - 66 != j.position[1] and self.drag[0] == j.position[0]:
                    self.touched_tile.run_action(move_down)
                    self.drag == False
                    print("I moved down")
                    return self.touched_tile and self.drag
                else:
                    self.drag == False
                    self.touched_tile == None
                    print("Failed")
                    return self.drag and self.touched_tile
                    
    #resets self.drag to intial False value for next touch to reset.                
    def touch_ended(self, touch): 
        if self.drag:
            self.drag = False
            return self.drag
    

    #CHECK FOR LOOPS

    if name == 'main':
    run(Game(), PORTRAIT, show_fps=True)
    )

    posted in Pythonista read more

Internal error.

Oops! Looks like something went wrong!