Trying a Qix clone.

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
kurai
Prole
Posts: 8
Joined: Fri Mar 18, 2011 9:52 pm

Trying a Qix clone.

Post by kurai »

I know I'm asking a lot, but I'm still learning :)
I was trying to make a small Qix clone, but I'm finding a lot of problems on even how to start.
Basically I want this cursor which movement is bound to the screen's edge and to the already closed lines.
When you press a button you can start to trace an orthogonal line. When you close a rectangle, the rectangle itself gets filled and you can freely move around its perimeter.
When you are tracing your lines, you are vulnerable to attacks not only in the cursor area, but even in the line you are tracing.

Now, I was trying to draw orthogonal lines with the love.graphics.line function, adding points to a table so to build a polyline.
But I've got all sort of problems to limit the direction of the cursor...

I feel lost, here. I need advice on how to proceed, pseudo code, anything pointing me in the right direction.
Can you help me?
User avatar
Lafolie
Inner party member
Posts: 809
Joined: Tue Apr 05, 2011 2:59 pm
Location: SR388
Contact:

Re: Trying a Qix clone.

Post by Lafolie »

Always post the latest version of your source code. Helps us understand and help you alot.
Do you recognise when the world won't stop for you? Or when the days don't care what you've got to do? When the weight's too tough to lift up, what do you? Don't let them choose for you, that's on you.
kurai
Prole
Posts: 8
Joined: Fri Mar 18, 2011 9:52 pm

Re: Trying a Qix clone.

Post by kurai »

Yes, the point is, the code is just a little stub, I don't even know if I'm moving in the right direction.
Right now is not working, because as soon as you start moving, you don't have two vertices to trace a line.

So, here it is, but I doubt it will be useful, probably I'm doing it completely wrong...

Code: Select all


function love.load()
	love.graphics.setMode(1024, 768, false, false)
	hero = {}
	hero.speed=100;

	hero.direction="none"
	hero.position ={}
	
	hero.x=10;
	hero.y=10;
end


function love.draw()
	if hero.direction ~= "none" then
		love.graphics.line(hero.position);
	end
end

function love.update(dt)
	if love.keyboard.isDown("left") then
		if hero.direction ~= "left" then
			hero.direction="left"
			table.insert (hero.position, hero.x, hero.y)
		end
		hero.x=hero.x-(hero.speed*dt)
	elseif love.keyboard.isDown("right") then
		if hero.direction ~= "right" then
			hero.direction="right"
			table.insert (hero.position, hero.x, hero.y)
		end
		hero.x=hero.x+(hero.speed*dt)
	elseif love.keyboard.isDown("up") then
		if hero.direction ~= "up" then
			hero.direction="up"
			table.insert (hero.position, hero.x, hero.y)
		end
		hero.y=hero.y-(hero.speed*dt)
	elseif love.keyboard.isDown("down") then
		if hero.direction ~= "down" then
			hero.direction="down"
			table.insert (hero.position, hero.x, hero.y)
		end
		hero.y=hero.y+(hero.speed*dt)
	end
end
User avatar
Lafolie
Inner party member
Posts: 809
Joined: Tue Apr 05, 2011 2:59 pm
Location: SR388
Contact:

Re: Trying a Qix clone.

Post by Lafolie »

Well for a start this line isn't valid syntax:

Code: Select all

      love.graphics.line(hero.position);
The syntax for graphics.line is:

Code: Select all

love.graphics.line( x1, y1, x2, y2, ... )
You made 2 errors - you didn't supply enough arguments to actually draw a line, and the first argument you passed was the wrong datatype; .line accepts numbers and not a table. If you wanted to use a table you could define your own function that breaks the table down as appropriate.

EDIT: I am an idiot. .line does indeed accept a table. Sorry about that.

But yeah, you still need to supply a second argument. At the moment you're attempting to draw a dot really. A line needs 2 sets of co-ords.
Do you recognise when the world won't stop for you? Or when the days don't care what you've got to do? When the weight's too tough to lift up, what do you? Don't let them choose for you, that's on you.
kurai
Prole
Posts: 8
Joined: Fri Mar 18, 2011 9:52 pm

Re: Trying a Qix clone.

Post by kurai »

I can see the problem.
But still, I cannot tell if this is the right direction for what I'm trying to do.
And still, I have no clue on how to limit the cursor movement only on the traced lines.
I really need some help to see clearer where I should go...
User avatar
miko
Party member
Posts: 410
Joined: Fri Nov 26, 2010 2:25 pm
Location: PL

Re: Trying a Qix clone.

Post by miko »

kurai wrote:I can see the problem.
But still, I cannot tell if this is the right direction for what I'm trying to do.
And still, I have no clue on how to limit the cursor movement only on the traced lines.
I really need some help to see clearer where I should go...
Don't worry, you are almost there.
Some random advices:
- limit x,y with max/min (or if)
- store only integer coordinates (unless you are using scaling)
- you either need a list of visited pixels (which is easier but memory-hungry), or a list of visited lines and some math (to check if a point is on one o those lines)
- if you will want to fill the enclosed area with another color, you probably will need to slice it to rectangles - filling polygons does not work nice in love2d for all polygons.
- you could also use framebuffers for filling with color/detecting visited points, but that would be slower

Here is my code:

Code: Select all

function love.load()
   love.graphics.setMode(1024, 768, false, false)
   hero = {}
   hero.speed=100;

   hero.position ={} 
   
   hero.x=10;
   hero.y=10;
   XMIN, XMAX, YMIN, YMAX=0,1024,0,768

   Visited={}

   enemy={position={x=0,y=0}, prev={x=-1,y=-1}}
end

function enemyNextPos()
  local e=enemy.position
  local p=enemy.prev
  local possible={}
  for _,d in ipairs({{-1,0},{1,0},{0,-1},{0,1}}) do
    local dx,dy=unpack(d)
    local x=e.x+dx
    local y=e.y+dy
    local visited=(Visited[x] and Visited[x][y]==true) or false
    local onEdge=(x==0 or x==1024 or y==0 or y==768)
    local onScreen=(x>=0 and x<=1024 and y>=0 and y<=768)
    local notPrev=not (x==p.x and y==p.y)
    if (visited or onEdge) and onScreen and notPrev then
      table.insert(possible, {x, y})
    end
  end
  return table.remove(possible, math.random(1, #possible))
end

function moveEnemy()
  local x,y=unpack(enemyNextPos())
  enemy.prev=enemy.position
  enemy.position={x=x, y=y}
end

function love.draw()
   --need at least 2 points to draw a line
   love.graphics.setColor(255,255,255,255)
   love.graphics.setLineWidth(3)
   love.graphics.rectangle('line', 0,0,1024,768)
   if #hero.position>=4 then
     love.graphics.setColor(0, 255,0,255)
     love.graphics.line(hero.position);
     love.graphics.circle('line', hero.x, hero.y, 5, 10)
   end
   love.graphics.setColor(255,0,0,255)
   love.graphics.circle('fill', enemy.position.x, enemy.position.y, 5, 10)
end

function love.update(dt)
  tick=(tick or 0)+dt*hero.speed
  if tick>1 then
     tick=tick-1
     local dx,dy=0,0
     if love.keyboard.isDown("left") then
       dx=-1
     elseif love.keyboard.isDown("right") then
       dx=1
     elseif love.keyboard.isDown("up") then
       dy=-1
     elseif love.keyboard.isDown("down") then
       dy=1
     end
     if dx~=0 or dy~=0 then
       -- insert only integer numbers
       local x=math.floor(hero.x)
       local y=math.floor(hero.y)
       if x~=LASTX or y~=LASTY then
         table.insert(hero.position, x)
         table.insert(hero.position, y)
         LASTX=x
         LASTY=y
         if not Visited[x] then Visited[x]={} end
         Visited[x][y]=true
       end
       hero.x=math.max(XMIN, math.min(XMAX, hero.x+dx))
       hero.y=math.max(YMIN, math.min(YMAX, hero.y+dy))
     end
  end
  moveEnemy()
  moveEnemy() --twice as fast
end
My lovely code lives at GitHub: http://github.com/miko/Love2d-samples
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 2 guests