I think this should be very easy to do, but I'm not able to find any solution. It's always just system.enable("multitouch") and then something with setFocus() method.
I have a right button, that responds to touch event and makes player run right when held. Then I have a jump button, that responds to tap event, making player jump.
Running works, jumping works, but when I run and try to jump nothing happens.
Here is some code:
local speed = 3
local motionx = 0
-- When right arrow is touched, move character right
function right:touch()
if string.find(player.sequence,"jump") then
player:setSequence("jumpRight")
motionx = speed;
elseif string.find(player.sequence,"duck") then
player:setSequence("duckRight")
else
player:setSequence("goingRight")
motionx = speed;
end
player:play()
end
right:addEventListener("touch",right)
-- When up arrow is tapped, jump character
function jump:tap()
if not isJumping then
if string.find(player.sequence, "goingRight") then
isJumping = true
player:setSequence("jumpRight")
player:setLinearVelocity(0,-120)
end
if string.find(player.sequence, "goingLeft") then
isJumping = true
player:setSequence("jumpLeft")
player:setLinearVelocity(0,-120)
end
if string.find(player.sequence, "duckLeft") then
player:setSequence("goingLeft")
end
if string.find(player.sequence, "duckRight") then
player:setSequence("goingRight")
end
player:play()
end
end
jump:addEventListener("tap",jump)
-- Move character
local function movePlayer (event)
player.x = player.x + motionx;
end
Runtime:addEventListener("enterFrame", movePlayer)
I don't knowh where, how or why should I use the setFocus() method. But so far when running, I cannot jump until I release the right button.
It was my mistake, that I wanted to use TAP event for jump. I guess since it is called multiTOUCH it only works with multiple TOUCH events :) I changed TAP events to TOUCH events and added:
if event.phase == "began" then
display.getCurrentStage():setFocus( event.target, event.id )
--other code
end
if event.phase == "ended" or event.phase == "cancelled" then
display.getCurrentStage():setFocus( event.target, nil )
end
Now it works nicely.
Related
I am developing a game for android with pygame and pygame_sdl2, and rapt for deploy.
Currently, the game is at a very first stage of development.
I have a joypad draw in the bottom left of my screen, and, when the mouse is pressed in the coordinates of the joypad's buttons, a character is moved according to the button durection. The mouse events are used as touch events as in this (working) example.
The problem is: the game is working on my laptop (I am using Ubuntu), but not on my mobile device. When I start the game, everything shows up as expected, but as soon as I touh the screen (no matter if it's on the buttons or somewhere else), the app goes in background.
My game is in a public github repo if you want to see the whole code (everything relevant is in the main.py file).
I think the error is triggered by the call to pygame.mouse.get_pressed().
Here is some relevant code which hopefully would help in understanding the problem.
Joypad class (btn_pressed method)
def btn_pressed(self, mouse_event):
# check if left mouse is being pressed
if pygame.mouse.get_pressed()[0]:
x, y = mouse_event.pos
if self.btn_up.rect.collidepoint(x, y):
return 'UP'
elif self.btn_down.rect.collidepoint(x, y):
return 'DOWN'
elif self.btn_left.rect.collidepoint(x, y):
return 'LEFT'
elif self.btn_right.rect.collidepoint(x, y):
return 'RIGHT'
Character class (move method)
def move(self, joypad_direction):
"""
move the character
to be used along with Joypad.btn_pressed returns
('UP', 'DOWN' 'LEFT', 'RIGHT')
"""
self.dx = 0
self.dy = 0
# check for horizontal move
if joypad_direction == 'LEFT':
self.dx = -self.speed
self.rect.move_ip(-self.speed, 0)
if joypad_direction == 'RIGHT':
self.dx = +self.speed
self.rect.move_ip(self.speed, 0)
self.dx = 0
# check for vertical move
if joypad_direction == 'UP':
self.dy = -self.speed
self.rect.move_ip(0, -self.speed)
if joypad_direction == 'DOWN':
self.dy = +self.speed
self.rect.move_ip(0, self.speed)
self.dy = 0
main loop
while True:
ev = pygame.event.wait()
# If not sleeping, draw the screen.
if not sleeping:
hero.move(joypad.btn_pressed(ev))
screen.fill((0, 0, 0, 255))
joypad.buttons.draw(screen)
if x is not None:
screen.blit(hero.image, (x, y))
pygame.display.flip()
As explained in the comments, there was an issue in my main loop.
I simply had to change my code from:
if not sleeping:
if not sleeping:
hero.move(joypad.btn_pressed(ev))
to:
if not sleeping:
if ev.type == pygame.MOUSEMOTION or ev.type == pygame.MOUSEBUTTONUP:
hero.move(joypad.btn_pressed(ev))
so that "Joypad class (btn_pressed method)" does not get an error when calling x, y = mouse_event.pos when the event was (e.g.) QUIT, thus not returning any coordinates (see also the image belowe taken from the pygame's event documentation page).
I am working on a game using Corona SDK , I have number of balls to display in game . i have implemented TouchListener to all of ball objects .
Code is here
local function ballTouchEvent(e)
local touchedBall = e.target
local phase = e.phase
if phase == "began" then
log("Touch began Phase")
elseif phase == "moved" then
log("Moved Phase")
elseif phase == "ended" or phase == "cancelled" then
log("Ended Phase")
end
return true
end
ball:addEventListener("touch",ballTouchEvent)
I want to implement some functionality when user touches on any of shown ball and moves his touch to white background (Place having no Ball) . Can any one guide me how to implement this ? Thanks in advance
Implement a React behind all of balls and implement click listener to that react. SO that when user leave the touch on white space, the ended phase of react listener will be called and you can put your implementation there what you want to do .
function scene:create( event )
sceneGroup = self.view
local rect = display.newRect(centerX, centerY, constants.screenWidth, constants.screenHeight)
-- rect:setFillColor( 0.0 )
rect.name = "background"
rect:addEventListener("touch",backTouchEvent)
sceneGroup:insert( rect )
end
You can add a group and then handle touch listener and do your work in group's end touch call.
Please visit the following link
Touch Event detection issue
Leading on from my last question, I have some obstacles which move across the screen. I need my app to go to the end game screen when my car (called "car") collides with one of the obstacles. Here is my code so far.
function obstacles()
local function onCollision( event )
if ( event.phase == "began" ) then
composer.gotoScene( "end", "fade", 500 )
end
end
local obstacle = display.newLine( display.contentWidth, display.contentHeight - 72, display.contentWidth, display.contentHeight - 102 )
obstacle:addEventListener( "collision", onCollision )
obstacle:setStrokeColor( 1, 0, 0, 1 )
obstacle.strokeWidth = 18
transition.to( obstacle, { time = 3000, x=-70, onComplete=obstacles } )
end
Whenever I seem to run the script and the car hits the obstacles nothing happens. Can anyone help please?
I don't know if your collision event is working, but your gotoScene function is not. You need to check the docs: gotoScene() function
You only need 2 parameters, the first is the name of the scene, the second is an optional table with parameters for the transition.
Try first to execute composer.gotoScene ("end")
If it works you can try:
local options = {
effect = "fade",
time = 500
}
composer.gotoScene( "end", options )
I am writing in Lua, using the Corona SDK, and I am looking to make an object inactive after a collision.
function onCollision(event)
if event.phase == "began" then
bullet.collided = true
bullet.isVisible = false
bullet:applyLinearImpulse(-5, 0, bullet.x, bullet.y)
explode(event)
end
end
function explode(event)
local x = event.object2.x
local y = event.object2.y
explosion.x = x
explosion.y = y
explosion.isVisible = true
explosion:play()
resetExplosion()
end
The above function takes the single bullet on the screen and makes it invisible after a collision with a ball that it shoots in the y axis. It then applys an impulse to remove it from the screen in the x-axis. My issue is that the ball (object2) in the collision is invisible after collision as well, but it still can be hit by the new bullet. There is only one bullet, so I can directly say bullet.whatever, but there is an array of balls, so the ball has to be addressed like ball[i].whatever.
is there a way to pass the index, i through the onCollision function?
You can set the body to inactive if you use a slight delay in your collision handler.
i.e:
-- Inside your Collision event
local function delay()
--Change the body's active state to false
body.isBodyActive = false
end
timer.performWithDelay( 10, delay )
According to CoronaSDK chapter about event.collision event.object1 and event.object2 are the properties identifying those collided objects (references to the bullet and one of the balls in Your case). So, doesn't it solve Your problem?
In my game, I want the camera to move based on the user swiping their finger. My issue is that when someone removes their finger from the screen, and places it down again, the camera jumps to a new position... I am guessing it has to do with the coordinates, I say this because if I click somewhere far from where I removed my finger from the screen, the camera jumps. Here is the code:
var speed : int = 1;
var lastPoint : Vector2; //make this private if you want to.
function Update()
{
var offset : float; //offset of the touch from last frame
if(Input.touches.Length 0)//make sure we have a touch in the first place
{
var evt : Touch = Input.touches[0]; //setting up touch events so we can get fancy.
if(evt.phase == TouchPhase.Began) //this is the first frame the screen has been touched for, simply save the point.
{
lastPoint == evt.position;
}
else if(evt.phase == TouchPhase.Moved
{
offset = evt.position.x - lastPoint.x ;//take the difference
//I'm going to use Transform.Rotate because it's handy dandy
transform.Rotate(0,offset * speed,0);
//save the new "lastPoint"
lastPoint = evt.position;
}
else if(evt.phase == TouchPhase.Ended)
{
//If you want the object to drift after you spin it you can make a function to go here.
//To do this, take the speed of the rotation and continue to rotate all while subtracting off of the speed.
//I would use the Transform.Rotate function on this too.
//If you need me to I could write this function too.
}
}
}
What is the solution to have the camera resume, and not jump once someone puts their finger down again?
I am also willing to redo it, if there is a better solution/more efficient method of solving the issue..
Thanks a lot!
The supplied code seems fine, all you need to do is when the user is not pressing, you update the lastPoint every frame. Or if you know when the user start to press, just set the lastPoint to the current pos before calculating the offset. This way the offset is zero the first frame the user touch the screen.