在Kivy App

时间:2016-08-02 17:33:06

标签: python python-3.x kivy

下面是我正在研究的一个小Kivy应用程序。目前我正在尝试实施基本的重置功能。基本上,如果敌人与玩家发生碰撞,我希望游戏重置。游戏结束时,在与敌人发生碰撞时取消时间安排。之后我想我可以在之后调用main(),但这只会导致游戏中左右错误的大量错误。我还尝试在unhedule之后添加了重新安排规则,但这只是覆盖了unhedule并保持游戏继续。

注意:游戏主要是从游戏类到代码底部处理。它也是您可以查看时钟安排规则的地方。

import kivy
kivy.require('1.1.1')

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty, ListProperty, NumericProperty, BooleanProperty
from kivy.core.audio import SoundLoader
import math
from kivy.clock import Clock
import time
import random

sound = SoundLoader.load('gamemusic.mp3')
PLAYER_SPEED = 10
ENEMY_SPEED = 4
ENEMY_SPAWN = 5
UPDATE_SPEED = .01
MIN_INITIAL_PLAYER_MINION_DISTANCE = 200
UPDATE_SCORE = 1
MAX_DECOYS = 3


if sound:
    sound.loop = True
    sound.play()


class Movable(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    target = ListProperty([])
    def move(self):

        dx = self.target[0] - self.center[0]
        dy = self.target[1] - self.center[1]
        total = math.sqrt(dx**2 + dy**2)
        if total >0:
            self.velocity_x = (dx / total) * self.speed
            self.velocity_y = (dy / total) * self.speed
            new_x = self.pos[0] + self.velocity_x
            new_y = self.pos[1] + self.velocity_y
            self.pos = (new_x,new_y)
        elif total <=0:
            self.velocity_x = self.speed
            self.velocity_y = self.speed


class Player(Movable):
    target = ListProperty([])
    def __init__(self, **kwargs):
        Widget.__init__(self)
        self.target = [399.0, 399.0]
        self.speed = PLAYER_SPEED
    def update_target(self, new_target):
        self.target = new_target
        if distance_pos(self.center, self.target) <= self.speed*2:
            self.target = self.center

class Enemy(Movable):
    randomColor = random.randint(0,1)
    alert = BooleanProperty(False)
    def __init__(self, **kwargs):
        Widget.__init__(self)
        self.world_width =  kwargs.get("width",0)
        self.world_height = kwargs.get("height",0)
        self.speed = ENEMY_SPEED
        x_target = float(random.randint(0, self.world_width))
        y_target = float(random.randint(0, self.world_height))

        self.target = [x_target, y_target]
        self.center = kwargs.get('start_pos',[0,0])
    def update_target(self, player, enemies, decoys):
        alert_list = self.alerted(enemies)
        if len(decoys) > 0:
            self.target = decoys[0].center
            self.alert = False
        elif distance(player, self) < 150:
            self.alert = True
            self.target = player.center
        elif len(alert_list) > 0:
            self.target = alert_list[0].center
            self.alert = False
        else:
            if distance_pos(self.center, self.target) <= self.speed*2:
                x_new_target = float(random.randint(0, self.world_width))
                y_new_target = float(random.randint(0, self.world_height))
                self.target = [x_new_target, y_new_target]
    def alerted(self, enemies):
        alert_list = []
        for item in enemies:
            if item.alert == True and distance(self, item) < 150:
                alert_list.append(item)
        return alert_list
class Decoy(Widget):
    def __init__(self, **kwargs):
        Widget.__init__(self)
        self.center = kwargs.get('start_pos',[0,0])
    pass

def distance(widget1, widget2):
    return distance_pos(widget1.center, widget2.center)
def distance_pos(pos1, pos2):
    dist = math.sqrt((pos1[0]-pos2[0])**2 + (pos1[1]-pos2[1])**2)
    return dist

class Game(Widget):
    player1 = ObjectProperty(None)
    enemies = ListProperty([])
    decoys = ListProperty([])
    score = NumericProperty()

    def setup(self):
        self.enemies = []
        self.decoys = []
        self.player1.center = self.center
        self.setup_schedules()
    #Don't forget about good code organization!
    def setup_schedules(self):
        Clock.schedule_interval(self.update, UPDATE_SPEED)
        Clock.schedule_interval(self.spawn_enemy, ENEMY_SPAWN)
        Clock.schedule_interval(self.increase_score, UPDATE_SCORE)



    def update(self,dt):
        self.player1.move()
        for item in self.enemies:
            item.update_target(self.player1,self.enemies,self.decoys)
            item.move()
            if self.player1.collide_widget(item):
                Clock.unschedule(self.spawn_enemy)
                Clock.unschedule(self.update)
                Clock.unschedule(self.increase_score)
    """
    def death_restart(self, player):
        if self.collide_widget(player):
            print("error")
            #main()
    """        
    def spawn_enemy(self, dt):
        if len(self.enemies) <= 8:
            x = float(random.randint(0, self.width))
            y = float(random.randint(0, self.height))
            enemy = Enemy(start_pos = (x,y),width = self.width,height = self.height)
            while distance(enemy, self.player1)< MIN_INITIAL_PLAYER_MINION_DISTANCE:
                x = float(random.randint(0, self.width))
                y = float(random.randint(0, self.height))
                enemy.pos = (x,y)

            self.enemies.append(enemy)
            self.add_widget(enemy)

    def spawn_decoy(self, location):
        x = location[0]
        y = location[1]
        decoy = Decoy(start_pos = (x,y))
        self.decoys.append(decoy)
        self.add_widget(decoy)

    def increase_score(self, dt):
        self.score += 1



    #on_touch_move vs on_touch_down
    def on_touch_move(self, touch):
        self.player1.update_target([touch.x, touch.y])

    def on_touch_down(self, touch):
        if touch.is_double_tap and len(self.decoys) < MAX_DECOYS:
            self.spawn_decoy([touch.x, touch.y])


#Entry Point into app

class GameApp(App):
    def build(self):
        game = Game()
        game.setup()        
        return game

def main():
    GameApp().run()

main()

0 个答案:

没有答案