psychopy 用状态机的思路写旋转随机点

状态机能够根据控制信号按照预先设定的状态进行状态转移,能够实现许多复杂的功能。在这个例子中,会呈现一些圆点,按空格可以控制它是否转动,按q可以退出。

一共有4种状态:

1、准备 demo未运行前,等待空格键发出开始的讯号。

2、运行 点已经在屏幕上旋转了。在这个状态里,要不断地获取上一帧到现在已经过去的时间,从而计算旋转的角度,绘制点。如果遇到空格键,就进入暂停状态,遇到q则退出

3、暂停 保留上一帧绘制的内容,不断重置计时器。如果遇到空格键,就继续旋转,遇到q则退出

4、退出 退出程序

下图表现了它们之间的关系

根据上图中的状态转换关系,可以写出如下核心代码:

def main():
    while True:
        if state == 'ready':
            event.waitKeys(['space'])
            state = 'running'
            
        elif state == 'running':
            keys = event.getKeys()
            if 'space' in keys:
                state = 'stop'
            elif 'q' in keys:
                state = 'quit'
                
        elif state == 'stop':
            keys = event.getKeys()
            if 'space' in keys:
                state = 'running'
            elif 'q' in keys:
                state = 'quit'

        elif state == 'quit':
            event.waitKeys(['space'])
            win.close()
            return 0

根据需要完成的效果在代码中添加计时和绘制功能,得到了实现效果的代码:

# -*- coding: utf-8 -*-
"""
Created on Wed Feb 22 18:06:33 2017

@author: zbg
"""

import random
from math import cos, sin, pi
from psychopy.visual import Window, ImageStim, TextStim, BufferImageStim, Rect, Circle, DotStim
from psychopy import core, event, gui, clock
import winsound

def CreatePoints():
    '''
    生成横坐标范围(-1, 1),纵坐标范围(-1, 1)的标准随机点。
    假设横纵坐标组成的正方形被切割成100个格子,纵横各10排
    每列每行各安排1个点,共10个
    '''
    array10 = [x / 5. + 1 / 10. - 1 for x in range(10)]
    random.shuffle(array10)
    arraya = array10[:]
    random.shuffle(array10)
    arrayb = array10[:]
    
    points = []
    for i in range(10):
        points.append((arraya[i], arrayb[i]))
    
    return points

def GetPoints(points, R, angle):
    '''
    把标准随机点按R放大,并旋转angle度
    '''
    points = points[:]
    a = angle / 180. * pi
    for i in range(len(points)):
        x, y = points[i]
        x, y = R * (x * cos(a) + y * sin(a)), R * (y * cos(a) - x * sin(a))
        points[i] = (x, y)

    return points

def ShowPoints(win, stim, points):
    for p in points:
        stim.fillColor = (random.random(), random.random(), random.random())
        stim.lineColor = (random.random(), random.random(), random.random())
        stim.setPos((p))
        stim.draw()
    win.flip()


def main():
    win = Window()
    stim = Circle(win, radius = 20, units = 'pix')
    points = CreatePoints()
    clk = clock.Clock() #用记录计每帧过去的时间
    time = 0 #用来记录总共过去的时间
    state = 'ready'
    R = 250
    r = 120 #每秒转动的角度
    
    
    while True:
        if state == 'ready':
            TextStim(win, text = u'准备,按空格开始').draw()
            win.flip()
            event.waitKeys(['space'])
            clk.reset()
            state = 'running'
            
        elif state == 'running':
            time += clk.getTime() #计算上一帧到现在所过去的时间
            clk.reset()
            ShowPoints(win, stim, GetPoints(points, R, time * r))
            keys = event.getKeys()
            if 'space' in keys:
                state = 'stop'
            elif 'q' in keys:
                state = 'quit'
                
        elif state == 'stop':
            clk.reset()#不启动计时器,
            
            keys = event.getKeys()
            if 'space' in keys:
                state = 'running'
            elif 'q' in keys:
                state = 'quit'

        elif state == 'quit':
            TextStim(win, text = u'按空格退出').draw()
            win.flip()
            event.waitKeys(['space'])
            win.close()
            return 0
        
main()

 

更多psychopy程序,尽在:

https://item.taobao.com/item.htm?spm=a230r.1.14.1.QRZDJq&id=530690095131&ns=1&abbucket=6#detail 

转载于:https://my.oschina.net/zbaigao/blog/843940

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值