riOwnage
riOwnage

Reputation: 37

How can I just make my widget move in Kivy?

I'm not having an awful lot of XP with programming and just starting with Kivy. I can't manage to find my way in the Kivy docs and youtube to combine everything, in this case make my widget move. Specially with the mix of kv and python and different layouts.

Right now I managed to print 'working' if I press the left button. Instead, I want to make my widget (car image) move automatically forward and rotate left and right with the 2 buttons as a car should turn.

Looking forward to see some suggestions. Also I hope somebody with a lot of Kivy experience have some tips of how to approach the kivy docs and kivy in general.

Here is my Python code:

import kivy
kivy.require('1.11.1')
from kivy.app import App
from kivy.uix.label import Label # add some text
from kivy.uix.stacklayout import StackLayout
from kivy.uix.gridlayout import GridLayout #
from kivy.uix.textinput import TextInput #for textinput ;)
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.pagelayout import PageLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.uix.image import Image, AsyncImage
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.button import Button
from kivy.uix.behaviors import ButtonBehavior
from kivy.graphics import Rectangle, Color
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.scatterlayout import ScatterLayout
from kivy.config import Config
from kivy.core.window import Window
from kivy.properties import ObjectProperty, NumericProperty, ReferenceListProperty, ListProperty
from kivy.vector import Vector
from kivy.clock import Clock
from kivy.lang import Builder
import os

Window.size = (450, 750)

print(dir(Widget))

class myGame(FloatLayout):

    def leftButton(self, *args):
        btnLeft = self.ids['btnLeft']
        Car.moveCar(self)

    def rightButton(self, *args):
        btnRight = self.ids['btnLeft']
        print('right button')


class Car(Widget):
    def moveCar(self):
        car = self.ids['car']
        print('working')




class myApp(App): #name your .kv file 'my.kv'
    def build(self): # initialization method, like __init__
        game = myGame()
        return game

if __name__ == '__main__':
    myApp().run()

Here is my kv code:

#:kivy 1.11.1


#<Button>:
    #size_hint: 0.5, 0.27

<FloatLayout>:
    Button:
        id: btnLeft
        pos_hint: {'x': 0, 'bottom': 1}
        size_hint: 0.5, 0.27
        on_press: root.leftButton()
        Image:
            source: 'images/arrow_left.png'
            allow_stretch: True
            keep_ratio: False
            center_x: self.parent.center_x
            center_y: self.parent.center_y  
            size: root.width * 0.5, root.height * 0.27


    Button:
        id: btnRight
        pos_hint: {'x': 0.5, 'bottom': 1}
        size_hint: 0.5, 0.27
        on_press: root.rightButton()
        Image:
            source: 'images/arrow_right.png'
            allow_stretch: True
            keep_ratio: False
            center_x: self.parent.center_x
            center_y: self.parent.center_y  
            size: root.width * 0.5, root.height * 0.27


    Car:      # the Car
        id: car
        canvas:
            Rectangle:
                source: 'images/car_blue_5.png'
                size: root.width * 0.15, root.height * 0.15
                pos: root.width * 0.425, root.height * 0.44

Upvotes: 0

Views: 1105

Answers (2)

Ahmed
Ahmed

Reputation: 11

In many plays you must use animation which it make your widget move in aduration and to a specific direction and it easy from the clock.

I use this app when you want to move the car you must press on buttons many times but in animation you can put a animation start when you on_press button and stop it when you release the button the animation repates if you want please visite.

https://kivy.org/doc/stable/api-kivy.animation.html

Upvotes: 0

John Anderson
John Anderson

Reputation: 38822

One way to make a Widget move is to use Animation, but if you want to keep changing the movement (steer), then you would probably want to do the animation yourself. Here is a version of your code that does that:

import kivy
kivy.require('1.11.1')
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.properties import NumericProperty, ListProperty
from kivy.clock import Clock
from kivy.lang import Builder

import math

Window.size = (450, 750)

class myGame(FloatLayout):

    def leftButton(self, *args):
        self.ids.car.direction_angle += 2

    def rightButton(self, *args):
        self.ids.car.direction_angle -= 2


class Car(Widget):
    speed = NumericProperty(20)
    direction_angle = NumericProperty(0)   # degrees
    direction = ListProperty([0,1])

    def __init__(self, **kwargs):
        super(Car, self).__init__(**kwargs)
        Clock.schedule_interval(self.moveCar, 0.1)

    def moveCar(self, dt):
        radians = self.direction_angle * math.pi / 180.0
        self.direction = math.sin(-radians), math.cos(-radians)
        self.pos = (self.x + dt * self.speed * self.direction[0], self.y + dt * self.speed * self.direction[1])


Builder.load_string('''
#:kivy 1.11.1


#<Button>:
    #size_hint: 0.5, 0.27

<FloatLayout>:
    Button:
        id: btnLeft
        pos_hint: {'x': 0, 'bottom': 1}
        size_hint: 0.5, 0.27
        on_press: root.leftButton()
        Image:
            source: 'images/arrow_left.png'
            allow_stretch: True
            keep_ratio: False
            center_x: self.parent.center_x
            center_y: self.parent.center_y  
            size: root.width * 0.5, root.height * 0.27


    Button:
        id: btnRight
        pos_hint: {'x': 0.5, 'bottom': 1}
        size_hint: 0.5, 0.27
        on_press: root.rightButton()
        Image:
            source: 'images/arrow_right.png'
            allow_stretch: True
            keep_ratio: False
            center_x: self.parent.center_x
            center_y: self.parent.center_y  
            size: root.width * 0.5, root.height * 0.27


    Car:      # the Car
        id: car
        size_hint: None, None
        size: root.width * 0.15, root.height * 0.15
        pos: root.width * 0.425, root.height * 0.44
        canvas.before:
            PushMatrix
            Rotate:
                angle: self.direction_angle
                origin: self.center
        canvas:
            Rectangle:
                source: 'images/car_blue_5.png'
                size: self.size
                pos: self.pos
        canvas.after:
            PopMatrix
''')


class myApp(App): #name your .kv file 'my.kv'
    def build(self): # initialization method, like __init__
        game = myGame()
        return game

if __name__ == '__main__':
    myApp().run()

The __init__() method of the Car starts the animation using a Clock.schedule_interval() call to update the Car position 10 times per second.

The movement of the Car is calculated in the moveCar() method and uses the direction_angle and speed to update the position.

The Buttons adjust the direction_angle property, which is used in the canvas of the Car to change its orientation.

Upvotes: 1

Related Questions