Howdy, Stranger!

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

Problem with adding multiple npc's

edited July 2014 in Questions Posts: 65

Yesterday I had the amazing idea to create a game where you play as a ghost and you have to take over people's bodies to solve puzzles. One of my problems is that I have no programming experience exept from what I learned from the forums and from little projects I made myself. I know it's hard to make good games and that it takes a lot of time but I still want to give it a shot. Another problem is that for some reason when I put down multiple npc's I can't take over bodies or leave bodies. If you're willing to share a solution, please don't make it too complicated as I don't want any code in my project that I don't understand!



  • edited July 2014 Posts: 65

    Here's the code:

    --# controls controls = class() function controls:init(x,y,subject,speed) -- you can accept and set parameters here self.x = x self.y = y self.moveleft=false self.moveright=false self.movedown=false self.moveup=false self.subject = subject self.speed = speed self.leftsize=50 self.rightsize=50 self.downsize=50 self.upsize=-50 end function controls:draw() -- Codea does not automatically call this method sprite("Cargo Bot:Command Left", self.x-50, self.y,self.leftsize) sprite("Cargo Bot:Command Right", self.x+50, self.y,self.rightsize) sprite("Cargo Bot:Command Grab",self.x, self.y-50, self.downsize) sprite("Cargo Bot:Command Grab", self.x, self.y+50, self.upsize) if self.moveleft==true then self.subject.x=self.subject.x-self.speed self.leftsize=60 end if self.moveright==true then self.subject.x=self.subject.x+self.speed self.rightsize=60 end if self.movedown==true then self.subject.y=self.subject.y-self.speed self.downsize=60 end if self.moveup==true then self.subject.y=self.subject.y+self.speed self.upsize=-60 end if self.subject.x<=0 then self.subject.x=0 end if self.subject.x>=WIDTH then self.subject.x=WIDTH end if self.subject.y<=0 then self.subject.y=0 end if self.subject.y>=HEIGHT then self.subject.y=HEIGHT end end function controls:touched(touch) -- Codea does not automatically call this method --dpad if touch.x<=self.x-25 and touch.x>=self.x-75 and touch.y<=self.y+25 and touch.y>=self.y-25 then self.moveleft=true end if touch.x<=self.x+75 and touch.x>=self.x+25 and touch.y<=self.y+25 and touch.y>=self.y-25 then self.moveright=true end if touch.x<=self.x+25 and touch.x>=self.x-25 and touch.y<=self.y-25 and touch.y>=self.y-75 then self.movedown=true end if touch.x<=self.x+25 and touch.x>=self.x-25 and touch.y<=self.y+75 and touch.y>=self.y+25 then self.moveup=true end if touch.state==ENDED then self.moveleft=false self.moveright=false self.movedown=false self.moveup=false self.leftsize=50 self.rightsize=50 self.downsize=50 self.upsize=-50 end end --# Ghost Ghost = class() function Ghost:init(x,y) -- you can accept and set parameters here self.x = x self.y = y self.tint = color(255, 255, 255, 152) end function Ghost:draw() -- Codea does not automatically call this method tint(self.tint) sprite("Planet Cute:Character Boy",self.x,self.y) noTint() end function Ghost:touched(touch) -- Codea does not automatically call this method end --# Main --Made by G_nex displayMode(FULLSCREEN) function setup() ghost=Ghost(WIDTH/2, HEIGHT/2) npc={} npc[1]=NPC(600, 600,"Planet Cute:Character Pink Girl",ghost) npc[2]=NPC(300, HEIGHT-300,"Planet Cute:Character Cat Girl",ghost) npc[3]=NPC(800, 200, "Planet Cute:Character Horn Girl", ghost) dpad=controls(150,150,ghost,5) music("Game Music One:Nothingness",true) end function draw() background(13, 210, 20, 255) for i=1,#npc do npc[i]:draw() end ghost:draw() --dpad dpad:draw() end function touched(touch) --classes dpad:touched(touch) for i=1,#npc do npc[i]:touched(touch) end end --# NPC NPC = class() function NPC:init(x,y,img,aff) -- you can accept and set parameters here self.x = x self.y = y self.img = img self.aff = aff self.takeover=false self.takenover=false end function NPC:draw() -- Codea does not automatically call this method sprite(self.img,self.x,self.y) if self.aff.x<self.x+50 and self.aff.x>self.x-50 and self.aff.y<self.y+50 and self.aff.y>self.y-50 then self.takeover=ask else self.takeover=false end if self.takeover==ask and dpad.subject==self.aff then fill(255, 255, 255, 255) rect(self.x+50, self.y, 150, 75) fill(0, 0, 0, 255) fontSize(20) textWrapWidth(500) font("Copperplate") text("Take body?", self.x+125, self.y+37) end if self.takeover==ask and dpad.subject==self then fill(255, 255, 255, 255) rect(self.x-200, self.y, 150, 75) fill(0, 0, 0, 255) text("Leave body?", self.x-125, self.y+37) end if self.takenover==1 then dpad.subject=self end if self.takenover==2 then dpad.subject=self.aff end end function NPC:touched(touch) -- Codea does not automatically call this method if self.takeover==ask and touch.x<=self.x+200 and touch.x>=self.x+50 and touch.y<=self.y+75 and touch.y>=self.y then self.takenover=1 end if self.takeover==ask and touch.x<=self.x-50 and touch.x>=self.x-200 and touch.y<=self.y+75 and touch.y>=self.y then self.takenover=2 end end

    I know it's kind of messy but I just found out how classes work so don't expect me to write everything super short but if it would help someone, you can use it for your own projects.

  • Posts: 65

    By the way, the game works properly when there's only one npc

  • Posts: 198

    It looks like you need to change takenover to self.takenover in th npc class init function. Right now their global variables so the program can't tell which npc is taken over.

  • Posts: 65

    Thanks, I don't know how I missed that though :-O but now I'm having another problem ~X(
    Well, I'll try to fix it myself before I ask for help again.

  • Posts: 65

    I don't like to ask it but could anyone help me with my other problem? Somehow the buttons act weird after 1 npc and I can't figure out why it does that... I edited the code above with the updated version.

  • Posts: 65

    Don't be afraid to help :P
    (I really want to continue the game as soon as I can.)

  • dave1707dave1707 Mod
    Posts: 8,725

    @G_nex I know you're in a hurry, so instead of trying to figure out why your code isn't working, it was faster to write another version of what I think you're doing to give you some other ideas. I didn't go into the detail you did. When the ghost and other sprites overlap, I put some text (switch) at the top of the screen. Tap it once to switch which sprite will then move. Only the ghost can switch with another sprite.

    displayMode(FULLSCREEN) supportedOrientations(LANDSCAPE_ANY) function setup() speed=2 -- speed to move dirX=0 -- x direction dirY=0 -- y direction str="" switch=false spriteMode(CENTER) tab={} -- table of sprites -- x position, y position, sprite, ghost tab[1]=xx(300,100,"Planet Cute:Star",true) tab[2]=xx(500,200,"Planet Cute:Character Cat Girl",false) tab[3]=xx(400,300,"Planet Cute:Character Horn Girl",false) tab[4]=xx(500,400,"Planet Cute:Character Pink Girl",false) tab[5]=xx(600,500,"Planet Cute:Character Princess Girl",false) end function draw() background(40, 40, 50) fill(255) for a,b in pairs(tab) do -- draw sprites in table b:draw() end -- movement arrows sprite("Cargo Bot:Command Left",100,150) sprite("Cargo Bot:Command Right",200,150) sprite("Cargo Bot:Command Grab",150,200,-50) sprite("Cargo Bot:Command Grab",150,100) switch=false text(str,WIDTH/2,HEIGHT-50) str="" end function touched(t) if t.state==BEGAN then if t.x>75 and t.x<125 and t.y>125 and t.y<175 then dirX=-speed -- move left end if t.x>175 and t.x<225 and t.y>125 and t.y<175 then dirX=speed -- move right end if t.x>125 and t.x<175 and t.y>175 and t.y<225 then dirY=speed -- move up end if t.x>125 and t.x<175 and t.y>75 and t.y<125 then dirY=-speed -- move down end if t.y>HEIGHT-150 then -- switch bodies switch=true end end if t.state==ENDED then -- set x,y directions to 0 dirX=0 dirY=0 end end xx=class() -- no name class function xx:init(x,y,sp,sel) self.x=x -- current x position self.y=y -- current y position self.sp=sp -- sprite to draw self.sel=sel -- which sprite is selected and moves if sel then self.ghost=true -- ghost sprite else self.ghost=false -- not ghost sprite end end function xx:draw() sprite(self.sp,self.x,self.y) if self.sel then -- move selected sprite self.x=self.x+dirX -- move in x direction self.y=self.y+dirY -- move in y direction end if not self.ghost then -- check for overlap with ghost if math.abs(tab[1].x-self.x)<25 and math.abs(tab[1].y-self.y)<25 then str="switch bodies" if switch then if tab[1].sel then -- switch from ghost to sprite tab[1].sel=false self.sel=true else tab[1].sel=true -- switch from sprite to ghost self.sel=false end end end end end
  • dave1707dave1707 Mod
    Posts: 8,725

    @G_nex Make the change I show below in the function NPC:draw(). Also, you're mixing values. Some places you set an initial value to false, then you set it later on to some number. Also, you use the variable "ask", but it's never set to anything, so it's nil. You need to go thru your code and find those kind of things, or you're going to have more trouble finding errors as the code gets bigger.

    function NPC:draw()   
         if self.takenover==2 then
            self.takenover=false        -- add this line
  • IgnatzIgnatz Mod
    Posts: 5,396

    @G_nex - what @dave1707 points out suggests that you may be rushing your code and writing too much at a time. This makes it very difficult to find errors.

    Try making very small changes and testing them properly before carrying on. This is actually a lot quicker overall.

  • Posts: 1,976

    @Ignatz Making small changes also helps for debugging, sometimes I've written a lot of code and pressed the play button to find there's an error in the ton of code I just wrote, and it tends to not tell me what line, or the line number can be incorrect.

  • IgnatzIgnatz Mod
    Posts: 5,396

    @TheSkyCoder - yes, that's exactly the point I was trying to make.

  • Posts: 65

    @dave1707 Thanks for helping' I said from the beginning my code was messy, but for now I'll take a break in writing new code and try to fix the current one.

    @Ignatz @SkyTheCoder Thanks for the tip. These kind of small tips really make a big difference at the end.

Sign In or Register to comment.