Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Help me make my code better

Hey I'm back again, not sure whether this should be posted here or in questions.

Anyhow, I was wondering if I could get some help for my code. I wanted to create a board with actual cases (not just background decoration). I would like to move the characters case by case (succeeded in my previous version) but would like that they can't go in it if the case is occupied. Also wondering how I could make it so the state (etat) changes when a character is inside it, I thought of making "if" loops but figured it is the same problem that I just stated, I need to figure out how to detect if a sprite is inside it.

PS: sorry if the code/outcome is messy, it was prettier in my previous version but it also wasn't coded the same way (cases drawn in a class instead of main etc). Hope you dont mind the french in the code as well but I can clear things up if needed thanks alot

Comments

  • IgnatzIgnatz Mod
    Posts: 5,396

    @Kostia - we'll have a look at it - but you forgot to post the code! :p

  • IgnatzIgnatz Mod
    Posts: 5,396

    Generally, if you have a board with characters in some of the places, you should use a table to tell you what is in each place.

    Then each time you draw, you can loop through all the items in the table, to find out what is in each place.

  • IgnatzIgnatz Mod
    Posts: 5,396

    you didn't post the GameLogic class

  • IgnatzIgnatz Mod
    edited February 2016 Posts: 5,396

    One thing you can do to make your classes neater, is to use inheritance, to share code between all the classes

    We define a base class with all the shared code. Then any class that wants to share that code "inherits" it, as shown below.

    --create functions that will be shared by several classes
    baseClass = class()
    
    function baseClass:touched(touch)
        if vec2(self.x,self.y):dist(vec2(touch.x,touch.y)) < 50 then 
            self.x=touch.x
            self.y=touch.y   
        end
        --etc all the rest of the shared touched code
    end
    
    --same for draw, note we need a variable self.sprite
    function baseClass:draw()
        spriteMode(CORNER)
        sprite(self.sprite,self.x+3,self.y+25,100,100)
    end
    
    --now create your different classes. If you want to change the
    --standard code above, simply replace the function
    
    Colon = class(baseClass) --inherits baseClass code
    
    function Colon:init(i,j,id)
       self.i = i-500
       self.j=j-500
       self.x=cote*self.i
       self.y=cote*self.j
       self.id=id
       self.sprite="Planet Cute:Character Princess Girl" --NOTE THIS
    end
    
    --you don't need a Colon touched or draw function because they are
    --the same as the base class
    
    
    Case = class() --Case doesn't use any standard code so DON'T inherit
    
    --all your Case functions are unchanged, same as before
    
    
    Exploreur = class(baseClass) --inherit  baseClass functions
    
    function Exploreur:init(i,j,id)
       self.i = i
       self.j=j
       self.x=cote*self.i
       self.y=cote*self.j
       self.id=id
       self.sprite="Planet Cute:Character Princess Girl" --NOTE THIS
    end
    
    --no need for draw or touched function, they are same as baseClass
    
    --if you wanted to change (say) the draw function for this class, just
    --rewrite it
    function Exploreur:draw()
        --whatever code you want (replaces baseClass code)
    end
    
    --you do need this extra function
    function Exploreur:cdde(p)
        q=math.random()
        if q<p then
            self.ph=self.ph
            else
            self.ph=math.random(1,2)
        end
        exploreur = class()      
    end
    
    --Guerrier class is similar
    
    
  • Posts: 12

    Yea I skipped the gamelogic because I ended up either putting everything inside Main or Case^^ Where did you see I had a Gamelogic class ?

    And thank you very much for the clearing up classes part! But if I understand, say I want to make an exception in one of the classes that use the baseclass. I can keep baseclass in this class but just put a different draw/touch function and it will ''overwrite'' the baseclass' priority ?

    btw Colon = Settler in english, I'm not into intestines dont worry :tongue:

  • Posts: 12

    Mhmm I modified my code and I now have the ''attempt to call method 'draw' (a nil value), which is my main and right after ''for i,objet in ipairs(guerriers) do
    objet:touched(CurrentTouch)
    objet:draw()''

    Any guesses^^?

  • dave1707dave1707 Mod
    edited February 2016 Posts: 10,053

    @Kostia I didn't look at all of your code to try and figure out everything you were trying to do, but here's some code I have that might be similar to what you describe at the top. You can move each Sprite around the board, but you can't move to a square already occupied. There are 3 characters, but more can be added. Also the number of each character can be changed if needed.

    PS. If you can't use this, maybe someone else can think of something to use this for. I don't have a use for it, I just wrote it for something to do.

    EDIT: Code removed to save space. See code farther down. Removed // and replaced with math.floor.

  • IgnatzIgnatz Mod
    Posts: 5,396

    @Kostia - yes, to overwrite a function from the base class, you just put in a function in the child class (try it with a little test project, I suggest).

    I don't know where the problem is, without seeing your code.

    And you will find the GameLogic error if you run the code you posted at the top.

  • Posts: 12

    Hi @dave1707 thanks for the code it tried it on it's own but I have Errors from the double slashes // and when removjng them I get an error line 53

    Attempt to index field ´?´ a nil value :tongue:

    And thanks @Ignatz I will have a look with my teacher tommorow :)

  • Posts: 2,020

    What version of Codea are you using? The double slashes are a Lua 5.3 feature. Codea switched from Lua 5.2 to 5.3 last March, with version 2.3

  • dave1707dave1707 Mod
    Posts: 10,053

    @Kostia Here's a version that doesn't use the // . You should update your version of Codea.

    supportedOrientations(PORTRAIT_ANY)
    displayMode(FULLSCREEN)
    
    function setup()
        spr={"Planet Cute:Character Pink Girl",
            "Planet Cute:Character Horn Girl",
            "Planet Cute:Character Cat Girl"}
        selected=0
        tab={}
        for x=1,13 do       
            tab[x]={}
            for y=1,19 do
                v=math.random(8)
                if v>3 then
                    v=0
                end
                tab[x][y]=v
            end
        end
        size=50
    end
    
    function draw()
        background(40, 40, 50)
        stroke(255)
        strokeWidth(2)
        for x=1,13 do
            for y=1,19 do
                rect(x*size,y*size,size,size)
                s=tab[x][y]
                if s>0 then
                    sprite(spr[s],x*size+25,y*size+35,50)
                end
            end
        end
        if selected>0 then
            sprite(spr[selected],tx,ty,50)
        end
    end
    
    function touched(t)
        x=math.floor(t.x/size)
        y=math.floor(t.y/size)
        if x<1 or x>13 or y<1 or y>19 then
            if selected>0 then
                set()
            end
            return
        end
        if t.state==BEGAN then
            tx,ty=t.x,t.y
            if tab[x][y]>0 then
                selected=tab[x][y]
                tab[x][y]=0
            else
                return
            end
        end
        if t.state==MOVING and selected>0 then
            if tab[x][y]==0 then
                tx,ty=t.x,t.y
            else
                set()
            end
        end
        if t.state==ENDED and selected>0 then
            set()
        end
    end
    
    function set()
        x=math.floor(tx/size)
        y=math.floor(ty/size)
        tab[x][y]=selected
        selected=0
    end
    
  • edited February 2016 Posts: 12

    Thank you everyone, but im kind of afraid to update the app though as it may cause bugs, no?

    Anyway, I got this done today, tell me what you think and what I should improve ^^ (I did find a couple of bugs myself but I don't know if it's worth fixing them haha)


    --# Main -- Isn2.4 Case = class() function Case:init(i,j,etat) -- you can accept and set parameters here self.i = i self.j = j self.etat = etat couleurs={color(255),color(255,0,0,255),color(9, 255, 0, 255),color(238, 0, 255, 255)} end function Case:draw() strokeWidth(6) stroke(couleurs[self.etat]) fill(0) rect(cotedam*self.i,cotedam*self.j,cotedam,cotedam) end function Case:touched(touch) -- Codea does not automatically call this method end Colon = class() function Colon:init(i,j,id) -- you can accept and set parameters here self.i = i self.j=j self.x=cote*self.i self.y=cote*self.j self.id=id self.i0=self.i self.j0=self.j end function Colon:draw() spriteMode(CORNER) sprite("Planet Cute:Character Princess Girl",self.x+3,self.y+25,100,100) end function Colon:touched(touch) if vec2(self.x,self.y):dist(vec2(touch.x,touch.y)) < 50 then self.x=touch.x self.y=touch.y end if touch.state==BEGAN or touch.state==MOVING then if (touch.x>cotedam*self.i and touch.x<cotedam*(self.i+1)) and (touch.y>cotedam*self.j and touch.y<cotedam*(self.j+1)) then self.x=touch.x-cote/2 self.y=touch.y-cote/2 end elseif touch.state==ENDED then if (touch.x>cotedam*(self.i-1) and touch.x<cotedam*(self.i+2)) and (touch.y>cotedam*(self.j-1) and touch.y<cotedam*(self.j+2)) then self.i=math.ceil(touch.x/cotedam)-1 self.j=math.ceil(touch.y/cotedam)-1 if cases[6*(self.i)+(self.j+1)].etat==1 then cases[6*(self.i)+(self.j+1)].etat=4 if self.i0~=self.i or self.j0~=self.j then cases[6*(self.i0)+(self.j0+1)].etat=1 self.i0=self.i self.j0=self.j end else self.i=self.i0 self.j=self.j0 end end -- limite du damier if self.i<0 then self.i=0 end if self.j<0 then self.j=0 end if self.i>nb_l then self.i=nb_l end if self.j>nb_h then self.j=nb_h end self.x=cotedam*self.i self.y=cotedam*self.j -- Codea does not automatically call this method end end Exploreur = class() function Exploreur:init(i,j,id) -- you can accept and set parameters here self.i = i self.j=j self.x=cote*self.i self.y=cote*self.j self.id=id self.i0=self.i self.j0=self.j end function Exploreur:draw() spriteMode(CORNER) sprite("Planet Cute:Character Boy",self.x+3,self.y+25,100,100) end -- Codea does not automatically call this method function Exploreur:cdde(p) q=math.random() if q<p then self.ph=self.ph else self.ph=math.random(1,2) end exploreur = class() end function Exploreur:touched(touch) if vec2(self.x,self.y):dist(vec2(touch.x,touch.y)) < 50 then self.x=touch.x self.y=touch.y end if touch.state==BEGAN or touch.state==MOVING then if (touch.x>cotedam*self.i and touch.x<cotedam*(self.i+1)) and (touch.y>cotedam*self.j and touch.y<cotedam*(self.j+1)) then self.x=touch.x-cote/2 self.y=touch.y-cote/2 end elseif touch.state==ENDED then if (touch.x>cotedam*(self.i-1) and touch.x<cotedam*(self.i+2)) and (touch.y>cotedam*(self.j-1) and touch.y<cotedam*(self.j+2)) then self.i=math.ceil(touch.x/cotedam)-1 self.j=math.ceil(touch.y/cotedam)-1 if cases[6*(self.i)+(self.j+1)].etat==1 then cases[6*(self.i)+(self.j+1)].etat=3 if self.i0~=self.i or self.j0~=self.j then cases[6*(self.i0) + (self.j0+1)].etat=1 self.i0=self.i self.j0=self.j end else self.i=self.i0 self.j=self.j0 end end -- limite du damier if self.i<0 then self.i=0 end if self.j<0 then self.j=0 end if self.i>nb_l then self.i=nb_l end if self.j>nb_h then self.j=nb_h end self.x=cotedam*self.i self.y=cotedam*self.j -- Codea does not automatically call this method end end Guerrier = class() function Guerrier:init(i,j,id) -- you can accept and set parameters here self.i = i self.j=j self.x=cotedam*self.i self.y=cotedam*self.j self.id=id self.i0=self.i self.j0=self.j end function Guerrier:draw() spriteMode(CORNER) sprite("Planet Cute:Character Horn Girl",self.x+3,self.y+3,100,100) end function Guerrier:touched(touch) if touch.state==BEGAN or touch.state==MOVING then if (touch.x>cotedam*self.i and touch.x<cotedam*(self.i+1)) and (touch.y>cotedam*self.j and touch.y<cotedam*(self.j+1)) then self.x=touch.x-cote/2 self.y=touch.y-cote/2 end elseif touch.state==ENDED then if (touch.x>cotedam*(self.i-1) and touch.x<cotedam*(self.i+2)) and (touch.y>cotedam*(self.j-1) and touch.y<cotedam*(self.j+2)) then self.i=math.ceil(touch.x/cotedam)-1 self.j=math.ceil(touch.y/cotedam)-1 if cases[6*(self.i)+(self.j+1)].etat==1 then cases[6*(self.i)+(self.j+1)].etat=2 if self.i0~=self.i or self.j0~=self.j then cases[6*(self.i0) + (self.j0+1)].etat=1 self.i0=self.i self.j0=self.j end else self.i=self.i0 self.j=self.j0 end end -- limite du damier if self.i<0 then self.i=0 end if self.j<0 then self.j=0 end if self.i>nb_l then self.i=nb_l end if self.j>nb_h then self.j=nb_h end self.x=cotedam*self.i self.y=cotedam*self.j -- Codea does not automatically call this method end end -- Civ Isn -- Use this function to perform your initial setup function setup() llc=100 cote=50 cotedam=110 nb_l=math.ceil(WIDTH/cotedam)-2 nb_h=math.ceil(HEIGHT/cotedam)-2 exploreurs={} table.insert(exploreurs, Exploreur(1,1)) guerriers={} table.insert(guerriers, Guerrier(5,5)) colons={} table.insert(colons, Colon(1,5)) cases={} for i=0,nb_l do for j=0,nb_h do table.insert(cases,Case(i,j,1)) end end end -- This function gets called once every frame function draw() background(1, 1, 1, 255) for i,objet in ipairs(cases) do objet:draw() end -- Do your drawing here for i,objet in ipairs(guerriers) do objet:touched(CurrentTouch) objet:draw() end for i,objet in ipairs(exploreurs) do objet:touched(CurrentTouch) objet:draw() end for i,objet in ipairs(colons) do objet:touched(CurrentTouch) -- print(CurrentTouch) --if CurrentTouch.state==ENDED then -- objet.x=objet.dpx --objet.y=objet.dpy -- end objet:draw() end end
  • dave1707dave1707 Mod
    Posts: 10,053

    @Kostia When you post code, put 3~'s on a line before and after your code so it formats correctly on the forum. I added them to your code above. I'm not sure what you're trying to do. It looks like you can move a character around the grid and if you try to move to a square near another character, that character will block your move. That could be the start to an interesting game. Not sure what the colored squares are for though.

  • dave1707dave1707 Mod
    Posts: 10,053

    @Kostia Updating Codea shouldn't cause any errors. A lot of people have already done it and if there were errors, they've been corrected already. You'll run into more problems with Codea by not updating than you will have by updating. But then that's up to you. If you're comfortable with the version you're on, that's fine. You'll have to learn the differences because most people won't modify their code so it works for you. You'll have to learn how to make those changes so they work with your version.

Sign In or Register to comment.