33 votes

Effet ondulé de l'eau Pygame

J'ai Cherché sur google mais il n'y a aucun prêt scripts - par opposition à le même effet sur Flash. J'ai vérifié l'algorithme sur L'Eau Effet Expliqué et également testé la mise en œuvre du Bruit de Perlin, qui fournit une bonne simulation de la fin d'ondes sur une surface plane. Je suis à la recherche pour la même application sur plusieurs Effets de Flash, basé sur mouseover/hover actions. C'est auprès d'un interactive étage de la bibliothèque, et je voudrais profiter de l'éloigner de Flash pour cette question, en particulier pour éviter de tels facile de reverse-engineering du code - et oui, je sais que ça pourrait simplement utiliser certains ready-made flash code, mais je ne l'utiliser que comme un dernier recours.

Quelqu'un a vu une mise en œuvre adaptée de cet effet pour Pygame (en utilisant OpenGL ou pas)?

EDIT: quelqu'un Peut-il fournir une mise en œuvre adaptée de cet effet à l'aide d'OpenCV/OpenGL et Pygame?

Le coupable est ici le (code) de l'interface pour passer d'une liste de valeurs qui seront envoyés à partir d'un interprète externe (tracker - pas TUIO si) via Python. J'ai essayé pendant quelques jours d'affilée, mais Pygame n'est pas en mesure de générer quelque chose d'aussi rapide que pure code C/C++ (utilisée pour les shaders OpenGL), et mes connaissances en C/C++ est null. Si la cible est au moins ce qui vient de code Python.

Un bon exemple, différent de l'effet de Flash mais qui est toujours de bon est de l'Eau de la Simulation à l'aide de l'applet Java.

(bounty est de montrer les réponses n'ont pas suffisamment de détails car c'était le plus proche de 'l'OP est incapable de créer le code qu'il veut comme il n'a pas les compétences fondamentales et cette réponse sera probablement de l'utilisation de plusieurs personnes").

9voto

leon Points 2108

Après avoir fait les devoirs (.k.un. de la recherche) et d'essayer de convertir directement le code Java de référence publiés sur la question en Python, et avoir un très, très triste expérience, tout en essayant d'avoir Python/Numpy mettre à jour une gigantesque gamme de couleurs des pixels en fonction de leur position pour le clapotis de l'effet d'entraînement (désolé, ma langue maternelle n'est pas l'anglais), donc l'analyse de plusieurs (x,y), les positions de chaque col de l'effet de calculs et de blitting que sur l'affiche de la surface sur l'écran (surfarray s'ensuit), Je suis venu à la conclusion - qui est appuyé par d'autres intervenants - que Pygame simplement de ne pas être assez puissant pour traverse l'ensemble de ce tableau de pixels et d'appliquer les résultats de calculs sur chaque pixel de l'écran à une fréquence minimale de 24 images par seconde (pour un moins-que-expérience moyenne).

Citant le très développeur derrière la Dernière Lumière des Productions et de l'ancien Projet Geometrian, Ian Maillet:

PyGame n'est pas si bon pour le pixel de pousser. Rien n'est, autre que le GPU.

La recherche s'est avéré être une recherche de Alkahest - quelque chose qui serait à son tour hors de n'être jamais vraiment trouvé - et basé sur la même idée de l'ondulation des images, mais cette fois en utilisant la transparence pour voir à travers plusieurs couches de Pygame surfaces, j'ai posté la question Pygame circulaire coropping/masques sur Gamedev. La réponse choisie fait corrobore le fait que je craignais déjà que Pygame ne serait jamais macho assez pour le travail.

Un jour plus tard, je suis retourné à mes idées antérieures sur le développement et suis tombé sur Ogre3D. Il s'avère que (1) Ogre3D et les échantillons sont open-source et (2) l'un des exemples est un 3-D de l'eau modèle qui interagit avec un objet en mouvement, exactement la même chose, j'ai essayé d'obtenir en 2-D, mais d'une manière beaucoup plus de manière professionnelle.

Depuis mes connaissances en C/C++ est nul, j'ai décidé de demander à propos de la façon de personnaliser le Ogre3D de l'eau de démonstration pour un aperçu de l'endroit où commencer la recherche, et l'une des réponses que m'a signalé logiciel de Touchscape où un SDK est fourni (voir cette réponse).

Ogre3D assez bien enveloppé. L'eau effet d'entraînement, OpenGL (qui peut éventuellement utiliser en fonction du matériel), le Moteur de Jeu et les wrappers Python via Python-Ogre - donc, ma réponse à ma propre question,

Quelqu'un peut-il fournir une mise en œuvre adaptée de cet effet à l'aide d'OpenCV/OpenGL et Pygame?

est fondamentalement

Oui. Vérifier Ogre3D d'eau de la démo, qui est fourni avec le kit de développement - et de le brancher en Python via Python-Ogre.

5voto

spam_eggs Points 847

Les éléments suivants à l'aide de numpy pourrait vous aider à démarrer. Il devrait être assez rapide car il est bien que vous pourriez obtenir beaucoup plus rapide même en python (avoir un coup d'oeil ici pour voir comment http://www.scipy.org/PerformancePython).

Par la route, il y a plusieurs inconvénients dans la méthode décrite :

  1. vous ne pouvez pas contrôler la vitesse des ondulations à faire cela, vous devez modifier les équations utilisées dans l'ondulation de la fonction (si vous comprendre comment il se rapporte à l'équation d'onde http://en.wikipedia.org/wiki/Wave_equation alors vous êtes fait)
  2. la "profondeur" de la "piscine" est fixe (et sans doute trop peu profonde). J'ai ajouté un paramètre de profondeur pour amplifier l'effet
  3. l'article entier les décalages des pixels - vous d'obtenir beaucoup plus de résultats avec les valeurs interpolées (je suppose que vous pouvez le faire avec opengl, mais mes connaissances dans ce domaine est nul)

code:

import numpy

def ripple(w1, w2, damp, n = 1):
    for _ in xrange(n):
        w2 *= -2
        w2[1:-1,1:-1] += w1[0:-2, 1: -1]
        w2[1:-1,1:-1] += w1[2:  , 1: -1]
        w2[1:-1,1:-1] += w1[1:-1, 0: -2]
        w2[1:-1,1:-1] += w1[1:-1, 2:   ]
        w2 *= .5 * (1. - 1./damp)
        w1, w2 = w2, w1

def refract(x, y, w, rindex, depth = 10):
    sx = x[0,1] - x[0,0]
    sy = y[1,0] - y[0,0]

    dw_dx = (w[2: ,1:-1] - w[:-2,1:-1]) / sx * .5
    dw_dy = (w[1:-1,2: ] - w[1:-1,:-2]) / sy * .5

    xang = numpy.arctan(dw_dx)
    xrefract = numpy.arcsin(sin(xang) / rindex)
    dx = numpy.tan(xrefract) * dw_dx * depth

    yang = numpy.arctan(dw_dy)
    yrefract = numpy.arcsin(sin(yang) / rindex)
    dy = numpy.tan(yrefract) * dw_dy * depth

    dx *= numpy.sign(dw_dx)
    dy *= numpy.sign(dw_dy)

    xmin = x[0,0]
    xmax = x[0,-1]
    x[1:-1,1:-1] += dx
    x[:,:] = numpy.where(x < xmin, xmin, x)
    x[:,:] = numpy.where(x > xmax, xmax, x)

    ymin = y[0,0]
    ymax = y[-1,0]
    y[1:-1,1:-1] += dy
    y[:,:] = numpy.where(y < ymin, ymin, y)
    y[:,:] = numpy.where(y > ymax, ymax, y)

x et y sont des grilles à partir d'un numpy.meshgrid appel : voici un exemple d'utilisation:

    x,y = meshgrid(x,y)
    w = 10 * exp(- (x*x + y*y))
    w1 = w.copy()
    x1,y1 = meshgrid(r_[0:len(x):1.0], r_[0:len(y):1.0])
    ripple(w, w1, 16) # w1 will be modified
    refract(x1, y1, w1, rindex=2, depth=10) # x1 and y1 will be modified
    numpy.around(x1, out=x1) # but you will get better results with interpolate
    numpy.around(y1, out=y1) # 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X