Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
Knife Hit mechanics - how to? - Gideros Forum

Knife Hit mechanics - how to?

Apollo14Apollo14 Member
edited May 6 in Code snippets
Hi guys!
How would you create 'Knife Hit' prototype?
(original gameplay is here:


(I've attached my current gproj with PNGs)
How to pin thrown knives to circle and make them rotate with circle?

I'm thinking about creating invisible parent for thrown knives, remove them from original parent and add them to invisible parent, just I'm not sure how to do it properly. And maybe there's another better way?

Currently I'm stuck here:
application:setBackgroundColor(0x2f3640)
centerX@240
centerY@427
local function playSound(sound) Sound.new(sound):play() end
 
--Add knives:
local knivesArr={}
for i=1,7 do
	knivesArr[i] = Bitmap.new(Texture.new("pics/knife.png",true))
	knivesArr[i]:setScale(0.3)
	knivesArr[i]:setAnchorPoint(0.5,0.5)
	knivesArr[i]:setPosition(centerX, centerY+250)
	stage:addChild(knivesArr[i])
	knivesArr[i]:setVisible(false)
end
currentKnifeCount=1
knivesArr[currentKnifeCount]:setVisible(true)
 
--Add circle:
local circle = Bitmap.new(Texture.new("pics/circle.png",true))
circle:setScale(0.5)
circle:setAnchorPoint(0.5,0.5)
circle:setPosition(240, 220)
stage:addChild(circle)
 
--Add apple to circle:
local apple = Bitmap.new(Texture.new("pics/apple.png",true))
apple:setScale(0.7)
apple:setAnchorPoint(0.5,0.5)
apple:setY(-325)
circle:addChild(apple)
 
--Rotate circle every frame:
local function onEnterFrameFunc()
	circle:setRotation(circle:getRotation()+1)
end
stage:addEventListener(Event.ENTER_FRAME, onEnterFrameFunc)
 
--Throw knife on tap:
local function throwKnife()
	playSound("sounds/throw.mp3")
	local knifeTween=GTween.new(knivesArr[currentKnifeCount], .15, {y = 410}, {delay = 0, ease = easing.linear,
		onComplete = function()
		playSound("sounds/hitWood.mp3")
		circle:setAlpha(1.2)
		local timerDelayed = Timer.delayedCall(100, function() circle:setAlpha(1) end)
 
		if currentKnifeCount
> Newcomers roadmap: from where to start learning Gideros
"What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
zip
zip
KnifeHit_Gideros.zip
261K

Comments

  • Apollo14Apollo14 Member
    edited May 5

    Nice looking game (the original).

    I also like it very much :smile:
    Though I definitely don't wanna make yet another clone (there're plenty of them already)

    I'm thinking about using this mechanics for a mini-game inside my main game.
    Like daily challenge, or daily slots.
    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
  • rrraptorrrraptor Member
    edited May 5
    Well, thats my version :) Developed a few months ago.

    There is my own VERY BASIC collision detection system, which is built on top of "SpartialHash" library. All it does is...checks for collisions :D (just true or false)

    It might be a bit complex to understand cuz no comments AT ALL :dizzy:

    P.S. Use it however you want, i dont care.

    Likes: Apollo14

    zip
    zip
    KnifeHit_clone.zip
    134K
    +1 -1 (+1 / -0 ) Share on Facebook
  • rrraptorrrraptor Member
    edited May 5
    In my project, i'm rotating all knifes around the wheel (idk why i did it this way, probably becouse of the collision system), but alternatively you can remove knife from parent, then add to wheel container and translate coordinates using globalToLocal method, oh and dont forget to rotate the knife so it will be facing to center of the wheel.
    ------------------------------------
    local dx, dy, w, h = application:getDeviceSafeArea(true)
     
    ScreenW = w+math.abs(dx)
    ScreenH = h+math.abs(dy)
     
    stage:setPosition(dx, dy)
     
    function CreateRect(w, h, ax, ay)
    	h = h or w
    	local p=Path2D.new()
    	local ms="MHVHVZ"
    	local mp={0,0, w, h, 0, 0}
    	p:setFillColor(0, 1)
    	p:setLineColor(0xffffff,1)
    	p:setPath(ms,mp)
    	if (ax and ay) then p:setAnchorPosition(w*ax,h*ay) end
    	return p
    end
     
    function CreateCircle(r)
    	local p=Path2D.new()
    	local ms="MAAZ"
    	local mp={-r,0, r,r,0,0,0,r,0, r,r,0,0,0,-r,0}
    	p:setPath(ms,mp)
    	p:setFillColor(0, 1)
    	p:setLineColor(0xffffff,1)
    	return p
    end
    ------------------------------------
    local tex = Texture.new("gfx/knipe.png", true)
    local wheelRad = 130
    local wheelY = 350
     
    TestScene = Core.class(Sprite)
     
    function TestScene:init()
    	self.knifes = {}
     
    	self:creteCircle()
     
    	self:addEventListener(Event.ENTER_FRAME, self.update, self)
    	self:addEventListener(Event.TOUCHES_BEGIN, self.touchBegin, self)
    end
     
    function TestScene:createKnife()
    	local btm = Bitmap.new(tex)
    	btm:setPosition(ScreenW / 2, ScreenH - 200)
    	btm:setAnchorPoint(0.5, 0.5)
    	btm:setRotation(-90)
    	self:addChild(btm)
     
    	return btm
    end
     
    function TestScene:creteCircle()
    	local thick = 4
    	self.circle = Sprite.new()
     
    	local circle = CreateCircle(wheelRad)
    	circle:setFillColor(0xDED6C0)
    	circle:setLineThickness(thick)
    	circle:setLineColor(0xAF685D)
    	self.circle:addChild(circle)
     
    	local ln = CreateRect(wheelRad - thick / 2, thick)
    	ln:setFillColor(0xD1A579, 1)
    	ln:setLineColor(0,0)
    	self.circle:addChild(ln)
     
    	self.circle:setPosition(ScreenW / 2, wheelY)
    	self:addChild(self.circle)
    end
     
     
    function TestScene:addToCircle(k)
    	k:removeFromParent()
    	local ox, oy = k:getPosition()
    	self.circle:addChild(k)
    	local x, y = self.circle:globalToLocal(ox, oy)
    	k:setRotation( k:getRotation() - self.circle:getRotation() )
    	k:setPosition(x, y)
    end
     
    function TestScene:update(e)
    	local dt = e.deltaTime
     
    	self.circle:setRotation(self.circle:getRotation() + 45 * dt)
     
    	for i = #self.knifes, 1, -1 do
    		local k = self.knifes[i]
    		local y = k:getY()
     
    		y -= 500 * dt
     
    		-- hit circle
    		if (y < wheelY + wheelRad) then
    			self:addToCircle(k)
    			table.remove(self.knifes, i)
    		else
    			k:setY(y)
    		end
    	end
    end
     
    function TestScene:touchBegin(e)
    	self.knifes[#self.knifes+1] = self:createKnife()
    end

    Likes: Apollo14

    +1 -1 (+1 / -0 ) Share on Facebook
  • antixantix Member
    edited May 5
    Here is a quick and messy solution which when the tween ends, uses setAnchorPosition() to set the knifes anchor position offset relative to where it would have hit the circle (kind of). Then it sets the knifes position to the circles position and every frame rotates it (like it does the circle). This gives the appearance that the knife is stuck to the circle.

    setAnchorPosition() is a fantastic method that people often overlook ;)
    application:setBackgroundColor(0x2f3640)
    centerX@240
    centerY@427
    local function playSound(sound) Sound.new(sound):play() end
     
    --Add knives:
    local knivesArr={}
    for i=1,7 do
    	knivesArr[i] = Bitmap.new(Texture.new("pics/knife.png",true))
    	knivesArr[i]:setScale(0.3)
    	knivesArr[i]:setAnchorPoint(0.5,0.5)
    	knivesArr[i]:setPosition(centerX, centerY+250)
    	stage:addChild(knivesArr[i])
    	knivesArr[i]:setVisible(false)
    end
    currentKnifeCount=1
    knivesArr[currentKnifeCount]:setVisible(true)
     
    --Add circle:
    local circle = Bitmap.new(Texture.new("pics/circle.png",true))
    circle:setScale(0.5)
    circle:setAnchorPoint(0.5,0.5)
    circle:setPosition(240, 220)
    stage:addChild(circle)
     
    --Add apple to circle:
    local apple = Bitmap.new(Texture.new("pics/apple.png",true))
    apple:setScale(0.7)
    apple:setAnchorPoint(0.5,0.5)
    apple:setY(-325)
    circle:addChild(apple)
     
    local knives = {}
     
    --Rotate circle every frame:
    local function onEnterFrameFunc()
    	circle:setRotation(circle:getRotation()+1)
     
    	-- rotate all knives that have been thrown at circle
    	for i = 1, #knives do
    		local knife = knives[i]
    		knife:setRotation(knife:getRotation() + 1)
    	end
     
    end
    stage:addEventListener(Event.ENTER_FRAME, onEnterFrameFunc)
     
    --Throw knife on tap:
    local function throwKnife()
    	playSound("sounds/throw.mp3")
    	local knifeTween=GTween.new(knivesArr[currentKnifeCount], .15, {y = 410}, {delay = 0, ease = easing.linear,
    		onComplete = function()
    		playSound("sounds/hitWood.mp3")
    		circle:setAlpha(1.2)
    		local knife = knivesArr[currentKnifeCount] -- get the current knife
                    knife:setPosition(circle:getPosition()) -- set knife to same position as circle
    		knife:setAnchorPosition(knife:getWidth() * 0.5, -620) -- offset knifes anchor position
                    knives[#knives + 1] = knife -- add it to knives to be rotated
     
    		local timerDelayed = Timer.delayedCall(100, function() circle:setAlpha(1) end)
     
    		if currentKnifeCount<7 then
    			currentKnifeCount+=1
    			knivesArr[currentKnifeCount]:setVisible(true)
    		else print("Round finished") end
    	end})
    end
    stage:addEventListener(Event.TOUCHES_END, throwKnife)
    You could attach the knife directly to the circle with addChild() but you would have to take into account scaling and stuff.. or.. resize your graphics so they don't need to be scaled.

    Likes: Apollo14

    +1 -1 (+1 / -0 ) Share on Facebook
  • Apollo14Apollo14 Member
    Wow! Both examples are awesome! So much stuff for me to learn! Thank you guys!

    Likes: antix

    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
    +1 -1 (+1 / -0 ) Share on Facebook
Sign In or Register to comment.