Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
A small snake game — Gideros Forum

A small snake game

AhBadianeAhBadiane Member
edited March 2013 in General questions
A small snake game

I want to create a small game of snake
The snake is composed of a header and 10 (or more) body members
Each part consists of a circle and covering slightly
The head (yellow) and will move the body (orange) should follow (see attach image)

I spent a lot of time on the examples supplied with Gideros and examples appcodingeasy.com Site

I analyzed:
b2.KINEMATIC_BODY: to have no gravity
b2.DistanceJoint: to keep the elements close
createFixture: I have more trouble
....

I'm sure the program (without moving) must take months to 100 lines, but I can not do

I need your help
Capture d’écran 2013-03-14 à 22.21.25.png
234 x 61 - 5K
AhBadiane

Comments

  • If there is nothing to do with physics, I think I can made this without attached bodies.

    1. Declare a snake Head circle. Declare others 9 circles, specify their position to form a snake, add these 9 pieces into a sprite group called grpSnakeBody

    On ENTER_FRAME event:
    1. Move Head by updating its position.
    2. Loop through grpSnakeBody, update their movement according to its head.
    3. Check if each of circle reach top edge of screen, then update it position to bottom edge, the same if it reach left edge then update its position to right edge.

    On MOUSE_UP event:
    4. Store event.x and event.y, store the current head position (headX, headY) then move the head to current event.x, event.y position
    5. Move all snake body items to the event.x, event.y when ever they reach headX, headY
  • AhBadianeAhBadiane Member
    edited March 2013
    @thanhquan1512, I think the solution is not so simple because the snake has to follow a path a bit complicated, not just a translation as shown in the diagram below
    I thought that would DistanceJoint the solution?
    Final.png
    253 x 63 - 10K
    AhBadiane
  • hgvyas123hgvyas123 Guru
    edited March 2013
    @AhBadiane
    not sure i am going to help you or going to make you more confuse :D

    @all
    i had made one small example
     
    function drawArc(xc,yc,xradius,yradius,startAngle,endAngle,isFill)
    	if yradius == nil then
    		yradius = xradius
    	end
    	if startAngle == nil then
    		startAngle = 0
    	end
    	if endAngle == nil then
    		endAngle = 360
    	end
    	if isFill == nil then
    		isFill = true
    	end
    	local shape = Shape.new()
    	if isFill then
    		shape:setFillStyle(Shape.SOLID, 0xffffff, 1)
    	else
    		shape:setLineStyle(3, 0x000000)
    	end
    	shape:beginPath()
    	for i=startAngle,endAngle do
    		if i==1 then
    			shape:moveTo(math.sin(math.rad(i)) * xradius, math.cos(math.rad(i)) * yradius)
    		else
    			shape:lineTo(math.sin(math.rad(i)) * xradius, math.cos(math.rad(i)) * yradius)
    		end
    	end
    	if isFill then
    		shape:closePath()
    	end
    	shape:endPath()
    	shape:setPosition(xc,yc)
    	return shape
    end
     
    local  myCircle = {}
    for i=1,10 do
    	myCircle[i] = drawArc(300+20*i,200,10)
    	stage:addChild(myCircle[i])
     
    end
     
     
     
    local function onEnterFrame()
    	for i=10,2,-1 do
    		myCircle[i]:setPosition(myCircle[i-1]:getPosition())
    	end
     
    	local x,y --speed variable
     
    	if math.random(100) < 50 then
    		x = 10
    	else
    		x = -10
    	end
     
    	if math.random(100) < 50 then
    		y = 10
    	else
    		y = -10
    	end
    	myCircle[1]:setPosition(myCircle[1]:getX()+x,myCircle[1]:getY()+y)
    end
    stage:addEventListener(Event.ENTER_FRAME,onEnterFrame,stage)
    it works perfectly [ yup i knows i am moving snake randomly and there is no control to handle it :D ] yuppy

    but now the problem is how can i increase the speed of snake if i change my speed variable x and y to 20 there is a big space between each circle :(

    any idea for this

    :)
  • Thank you @ hgvyas123
    By changing the function onEnterFrame (), I should do it (avoid gaps or overlaps that gives a tiny snake)
    But I remain convinced that the solution lies in http://appcodingeasy.com/Gideros-Mobile/Gideros-Box2d-Chains-and-Elastic-Ropes example, but the code is too complex for me :((
    AhBadiane
  • ar2rsawseenar2rsawseen Maintainer
    @AhBadiane do you need a simply draggable snake? Then yes it would be easier with box2d.

    But if you want a traditional snake game, then there won't be much of a point from box2d, because you would have to update position of each cell manually (without box2d) in loop, to match position of previous cell, basically what @hgvyas123 did.

    So what exactly do you want?
  • ScouserScouser Guru
    edited March 2013 Accepted Answer
    Similar to what @hgvyas123: is doing buy have a head circle and make the other pieces children of the head, then you only need to move the 1 object to start with.
    function snake:init()
    	local parent = stage
    	self.myCircle = {}	-- The snake
    	local circle
    	local xp, yp = 100,300
    	local rad = 10		-- radius
    	self.rad = rad
    	self.xp, self.yp = xp, yp
    	self.dx = 0		-- movement delta x
    	self.dy = -1		-- movement delta y moves snake up
    	for i=1,10 do
    		circle = self:drawArc(xp,yp,rad)		-- create a segment
    		self.myCircle[i] = circle			-- add to our snake array
    		parent:addChild(circle)			-- chain object to our parent object
    		parent = circle					-- new parent object
    		xp = -self.dx*rad*1.8
    		yp = -self.dy*rad*1.8				-- Position relative to parent
    	end
    	self:addEventListener(Event.ENTER_FRAME,self.onEnterFrame,self)	
    end
     
    function snake:onEnterFrame(event)
    	local nx = self.xp + self.dx	-- Next x position
    	local ny = self.yp + self.dy	-- Next y position
    	local rr = math.random(1000)	-- Random number
    	local dir = 0
    	if 	nx < self.rad or nx > (appWidth-self.rad) or
    		ny < self.rad or ny > (appHeight-self.rad) or
    		rr > 990 then		-- Must turn if at edge of screen or rand(1000)>990
    		if rr > 995 then dir = 1
    		else dir = 2 end
    		if self.dx == 0 then
    		-- Moving up/down so let's change to left/right
    			if dir == 1 then 	-- turn right
    				self.dx = self.dy
    				self.dy = 0
    			else
    				self.dx = -self.dy
    				self.dy = 0
    			end
    		else
    			if dir == 1 then 	-- turn right
    				self.dy = self.dx
    				self.dx = 0
    			else
    				self.dy = -self.dx
    				self.dx = 0
    			end
    		end
    	end
     
    	self.xp = self.xp + self.dx		-- Update new positions
    	self.yp = self.yp + self.dy
    	self.myCircle[1]:setPosition(self.xp, self.yp)
    end
    Extra code is required to check the segments of the snake and change their position relative only to their parent and again only one segment needs to change at a time.

    Hope this helps
  • ar2rsawseenar2rsawseen Maintainer
    edited March 2013
    @Scousers @hgvyas123 so now it's a contest?
    Moving snake in shortest possible code? :D
  • ScouserScouser Guru
    edited March 2013
    No contest, just my take on things.

    Using @hgvyas123's method all segments have to be re-calculated every time.

    Using my method only the head has to be recalculated unless the snake has changed direction then only one segment needs moving at a time until they are all going in the same direction. :D
  • Thx @Scouser, I will test your solution tomorrow
    @ar2rsawseen, you ask the right question. My snake must control a ball in a breakout. It replaces the classic paddle
    AhBadiane
  • ok no problem i accept that i had won :D

    :)

Sign In or Register to comment.