This part of my code is meant to create two shapes on either side of shape already displayed.
pygame.draw.circle(screen, black, button_positions[i], button_radius)
pygame.draw.polygon(screen, white, button_star_points[i])
if i == 0:
g = random.choice([1,2])
if g == 1:
j = 2
elif g == 2:
j = 1
if i == 1:
g = random.choice([0,2])
if g == 0:
j = 2
elif g == 2:
j = 0
if i == 2:
g = random.choice([0,1])
if g == 0:
j = 1
elif g == 1:
j = 0
pygame.draw.polygon(screen, white, button_triangle_points[g])
pygame.draw.polygon(screen, white, button_heart_points[j])
pygame.display.update()
Here is the full code block for reference.
import pygame
import csv
import time
import math
import random
from datetime import datetime
#import RPi.GPIO as GPIO
#from picamera2 import Picamera2 , Preview
#from libcamera import controls
#from picamera2.encoders import H264Encoder
# Constants
ITI = 2 # Inter-trial interval in seconds
# Initialize pygame starts
pygame.init()
# Set the dimensions of the screen
screen_width = 1275
screen_height = 750
# Set the colors
white = (255, 255, 255)
black = (0, 0, 0)
# Set the font
font = pygame.font.SysFont('Arial', 20)
# Set the button properties
button_radius = 70
button_x_spacing = 400
button_y_spacing = 200
# Set the button positions
button_positions = [
(button_x_spacing, button_y_spacing),
(button_x_spacing, button_y_spacing + 200),
(button_x_spacing, button_y_spacing + 400)
]
# Drawing Star Function
def generate_star_points(center_x, center_y, outer_radius, inner_radius, points):
star_points = []
step = 2 * math.pi / points
half_step = step / 2
start_angle = -math.pi * 2 # Start the star with one point facing to the right
for i in range(points):
set_point = lambda angle, radius: (
int(center_x + math.cos(angle - start_angle) * radius),
int(center_y - math.sin(angle - start_angle) * radius)
)
outer_point_angle = i * step
inner_point_angle = outer_point_angle + half_step
star_points.append(set_point(outer_point_angle, outer_radius))
star_points.append(set_point(inner_point_angle, inner_radius))
return star_points
# Create the star points for each button
num_points = 5 # Number of points in the star
outer_radius = button_radius # Outer radius of the star
inner_radius = button_radius * 0.5 # Inner radius of the star
# List for star points
button_star_points1 = generate_star_points(button_x_spacing, button_y_spacing, outer_radius, inner_radius, num_points)
button_star_points2 = generate_star_points(button_x_spacing, button_y_spacing + 200, outer_radius, inner_radius, num_points)
button_star_points3 = generate_star_points(button_x_spacing, button_y_spacing + 400, outer_radius, inner_radius, num_points)
button_star_points = [button_star_points1, button_star_points2, button_star_points3]
# Creating the triangle points
def create_triangle(center_x, center_y, radius):
num_points = 3 # For a triangle
points = []
for i in range(num_points):
angle = 2 * math.pi * i / num_points
x = center_x + int(radius * math.cos(angle))
y = center_y + int(radius * math.sin(angle))
points.append((x, y))
return points
# List for triangle points
button_triangle_points1 = create_triangle(button_x_spacing, button_y_spacing, button_radius)
button_triangle_points2 = create_triangle(button_x_spacing, button_y_spacing + 200, button_radius)
button_triangle_points3 = create_triangle(button_x_spacing, button_y_spacing + 400, button_radius)
button_triangle_points = [button_triangle_points1, button_triangle_points2, button_triangle_points3]
button_heart_points1 = []
button_heart_points2 = []
button_heart_points3 = []
num_points = 100 # Increase this value for a smoother heart shape
radius = button_radius
for i in range(num_points):
angle = 2 * math.pi * i / num_points
x1 = button_x_spacing + int(radius * (13 * math.cos(angle) - 5 * math.cos(2 * angle) - 2 * math.cos(3 * angle) - math.cos(4 * angle)) / 16)
y1 = button_y_spacing + int(radius * math.sin(angle) ** 3)
x2 = button_x_spacing + int(radius * (13 * math.cos(angle) - 5 * math.cos(2 * angle) - 2 * math.cos(3 * angle) - math.cos(4 * angle)) / 16)
y2 = button_y_spacing + 200 + int(radius * math.sin(angle) ** 3)
x3 = button_x_spacing + int(radius * (13 * math.cos(angle) - 5 * math.cos(2 * angle) - 2 * math.cos(3 * angle) - math.cos(4 * angle)) / 16)
y3 = button_y_spacing + 400 + int(radius * math.sin(angle) ** 3)
button_heart_points1.append((x1, y1))
button_heart_points2.append((x2, y2))
button_heart_points3.append((x3, y3))
button_heart_points = [button_heart_points1, button_heart_points2, button_heart_points3]
# Inputs
trials = int(input("Number of trials: "))
AnimalName = input("Animal Name: ")
Trial_Duration = int(input("Trial Duration (s): "))
# Setting up Camera
#camera = Picamera2()
#vidconfig = camera.create_video_configuration()
#camera.configure(vidconfig)
#encoder = H264Encoder(bitrate=10000000)
#vidname = f"{AnimalName}_WCST_S3_{datetime.now().strftime('%Y%m%d_%H%M%S')}_Video.h264"
#camera.start_preview(Preview.QTGL)
#camera.start_recording(encoder,vidname)
#camera.annotate_text = f"{AnimalName}_WCST_S3_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
# Initialize the screen
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
# Set the caption
pygame.display.set_caption("Marmoset Buttons")
# Set the clock
clock = pygame.time.Clock()
# Set the counters
correctleft = 0
correctmiddle = 0
correctright = 0
incorrectleft = 0
incorrectmiddle = 0
incorrectright = 0
trialnum = 0
timeouts = 0
# Set the lists
timelistleft = []
timelistmiddle = []
timelistright = []
summarysequence = []
# GPIO Setup
#GPIO.setmode(GPIO.BCM)
#GPIO.setwarnings(False)
# Psuedorandom sequence of numbers
sequence = [1,1,2,2,1,2,1,0,1,1, 1,2,1,0,1,0,1,2,1,1, 2,1,0,1,2,1,1,0,1,2, 2,1,0,2,1,1,1,0,1,1,
1,1,0,1,1,1,2,0,2,1, 2,1,0,1,0,1,1,2,2,1, 1,0,1,1,0,0,1,1,2,2, 1,1,2,1,1,2,1,0,1,1,
1,1,1,0,1,1,2,0,2,1, 0,1,1,2,1,0,1,2,1,0, 1,1,0,1,1,2,1,2,1,0, 2,1,2,1,1,2,1,1,0,1,
1,0,1,1,0,1,1,1,1,1, 1,1,2,1,1,1,0,1,1,2, 1,2,1,0,1,2,2,2,1,0, 1,2,1,0,0,1,2,1,2,0,
1,0,1,1,1,0,1,1,2,1, 0,1,2,2,1,1,1,0,1,1, 1,0,1,2,0,1,0,1,1,2, 0,1,2,1,2,1,2,2,1,0,
1,1,1,0,1,1,0,1,1,0, 1,2,2,1,0,1,1,2,0,1, 1,0,1,2,1,0,1,2,1,0, 1,0,1,1,2,2,1,1,0,0,
1,2,1,2,1,1,1,0,1,0, 1,1,0,1,2,1,1,2,1,0, 1,2,1,1,0,1,0,1,1,0, 1,2,0,2,1,2,1,0,0,1,
1,1,1,1,0,0,1,2,0,1, 0,1,2,0,1,2,1,2,1,0, 1,0,1,2,1,1,2,0,1,2, 0,0,1,0,2,1,2,1,2,1,
1,2,2,2,1,1,2,1,1,0, 1,2,1,1,0,2,1,2,1,1, 1,2,2,1,1,2,1,0,0,1, 2,1,2,1,0,2,1,2,0,0,
1,0,1,1,2,2,1,0,1,0, 0,1,2,1,1,0,1,2,0,1, 1,0,0,1,2,1,2,1,0,0, 1,2,0,0,2,1,0,2,1,1,
1,1,1,1,2,1,1,0,1,1, 2,1,0,1,1,0,1,2,1,0, 0,1,2,1,2,1,0,1,2,1, 2,1,0,2,1,2,1,1,2,1,
1,1,0,1,1,1,2,1,1,1, 2,1,2,1,0,0,1,2,1,2, 1,0,1,2,1,2,0,1,2,2, 2,0,1,2,1,2,1,0,1,1,
1,2,1,0,1,2,0,2,2,2, 1,2,2,1,1,0,1,1,0,0, 1,1,0,1,0,0,1,2,1,2, 1,0,2,1,2,1,2,1,0,1,
1,2,1,1,0,1,1,0,0,1, 1,1,1,2,1,1,0,1,1,1, 1,2,1,0,2,2,1,2,0,1, 1,1,2,2,1,0,1,2,1,0,
1,2,0,1,1,0,1,1,2,1, 1,2,2,2,1,1,1,0,1,0, 1,2,0,0,0,1,2,2,0,1, 0,2,1,0,0,1,2,2,2,1,
1,1,2,1,0,1,0,1,2,1, 1,2,1,0,1,1,2,1,0,2, 1,0,2,2,1,0,1,0,2,1, 1,0,2,1,2,1,1,0,0,1,
1,2,1,2,1,1,1,0,1,1, 1,1,0,0,1,2,1,2,1,0, 1,2,1,2,2,1,0,1,0,0, 2,1,0,2,0,1,0,1,2,1,
1,1,0,1,0,1,1,1,0,1, 1,2,1,0,1,0,1,2,1,0, 2,1,2,2,1,0,1,0,1,1, 2,1,2,0,1,2,1,2,0,0,
1,1,2,0,2,1,2,1,1,0, 1,2,1,0,0,1,1,2,1,2, 1,2,2,1,1,1,1,2,0,0, 1,2,1,0,0,2,1,0,2,1,
1,0,1,1,2,1,2,0,1,2, 2,1,0,1,1,0,1,2,1,0, 0,1,0,1,2,1,1,2,1,0, 2,2,1,0,0,1,2,1,2,1]
# Truncating list
#trials = int(input("Number of trials: "))
n = len(sequence)
for i in range(0, n - trials):
sequence.pop()
# Setting up CSV title
thedatetime = datetime.now()
thetime = thedatetime.strftime("%H:%M:%S")
title = f"{AnimalName}_WCST_S5a_SimpleShape2_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
# Write headers to csv file
data = open(title, 'w')
writer = csv.writer(data)
writer.writerow(["Trial#", "Event Code", "Time"])
time_start = time.time()
# For loop parsing through sequence
for i in sequence:
trialnum += 1
summarysequence.append(i)
# Writing summary csv
if trialnum%10 == 0:
if trialnum == 10:
title2 = f"{AnimalName}_WCST_S5a_SimpleShape2_{datetime.now().strftime('%Y%m%d_%H%M%S')}_Summary.txt"
summary = open(title2, "a+")
summary.write(f"Trial Duration: {Trial_Duration}\n")
summary.write(f"ITI: {ITI}\n")
meanleft = sum(timelistleft) / len(timelistleft)
meanmiddle = sum(timelistmiddle) / len(timelistmiddle)
meanright = sum(timelistright) / len(timelistright)
summary.write(f"Completed Trials (saved every 10th): {trialnum}\n")
summary.write("Sequence: " + str(summarysequence) + "\n")
summary.write(f"Correct: {correctleft},{correctmiddle},{correctright}\n")
summary.write(f"Incorrect: {incorrectleft},{incorrectmiddle},{incorrectright}\n")
summary.write(f"Total Reward: {correctleft+correctmiddle+correctright}\n")
summary.write(f"Total No Reponses: {timeouts}\n")
summary.write(f"Mean Reaction Times: {meanleft}, {meanmiddle}, {meanright}\n")
summary.write("------------------------------------------------------------\n")
# Delay between buttons
screen.fill(black)
pygame.display.update()
# ITI
time_before = time.time()
loop_counter = 0
while time.time() - time_before < ITI:
pygame.draw.rect(screen, white, pygame.Rect(button_x_spacing - 10, button_y_spacing + 200 - button_radius + 10, 20, button_radius*2 - 20))
pygame.draw.rect(screen, white, pygame.Rect(button_x_spacing - button_radius + 10, button_y_spacing + 200 - 10, button_radius*2 - 20, 20))
pygame.display.update()
pygame.time.delay(100)
pygame.event.pump()
if pygame.mouse.get_pressed()[0]:
if i == 0:
writer.writerow([trialnum, 210, time.time() - time_start])
elif i == 1:
writer.writerow([trialnum, 211, time.time() - time_start])
elif i == 2:
writer.writerow([trialnum, 212, time.time() - time_start])
screen.fill(black)
pygame.display.update()
# While loop variable
correct = False
# Starts Timer
#start_time = pygame.time.get_ticks()
start_time = time.time()
# Writing the button in csv file
timedisplay = time.time()
writer.writerow([trialnum, i, timedisplay - time_start])
# Loops while button isn't correct
while correct == False:
# Time out for 15 seconds
seconds = (time.time() - start_time)
if seconds >= Trial_Duration:
timeouts +=1
timenow = time.time()
writer.writerow([trialnum, 250, timenow - time_start])
break
# Checks when screen is touched
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
# Distance between point touched and button
distance_button = pygame.math.Vector2(button_positions[i]) - pygame.math.Vector2(pygame.mouse.get_pos())
# Checks if distance is within button
if distance_button.length() < button_radius:
correct = True
timecorrect = time.time()
writer.writerow([trialnum, 150, timecorrect - time_start])
# Reward
#GPIO.setup(12,GPIO.OUT)
#GPIO.output(12,GPIO.HIGH)
#time.sleep(0.1)
#GPIO.output(12,GPIO.LOW)
#GPIO.cleanup()
# Counts which buttons were pressed
if i == 0:
timecorrect = time.time()
timedifference = timecorrect - timedisplay
timelistleft.append(timedifference)
correctleft += 1
elif i == 1:
timecorrect = time.time()
timedifference = timecorrect - timedisplay
timelistmiddle.append(timedifference)
correctmiddle += 1
elif i == 2:
timecorrect = time.time()
timedifference = timecorrect - timedisplay
timelistright.append(timedifference)
correctright += 1
# Counts when touch was outside of button
elif distance_button.length() > button_radius:
correct = True
x, y = pygame.mouse.get_pos()
if y <= (screen_height/3):
incorrectleft += 1
timenow = time.time()
writer.writerow([trialnum, 201, timenow - time_start])
elif y <= 2*(screen_height/3):
incorrectmiddle += 1
timenow = time.time()
writer.writerow([trialnum, 200, timenow - time_start])
elif y > 2*(screen_height/3):
incorrectright += 1
timenow = time.time()
writer.writerow([trialnum, 202, timenow - time_start])
# Draws the button
pygame.draw.circle(screen, black, button_positions[i], button_radius)
pygame.draw.polygon(screen, white, button_star_points[i])
if i == 0:
g = random.choice([1,2])
if g == 1:
j = 2
elif g == 2:
j = 1
if i == 1:
g = random.choice([0,2])
if g == 0:
j = 2
elif g == 2:
j = 0
if i == 2:
g = random.choice([0,1])
if g == 0:
j = 1
elif g == 1:
j = 0
pygame.draw.polygon(screen, white, button_triangle_points[g])
pygame.draw.polygon(screen, white, button_heart_points[j])
pygame.display.update()
# Closing objects
data.close()
summary_contents = summary.read()
print(summary_contents)
summary.close()
#camera.stop_recording()
#camera.stop_preview()
It displays both the triangle and the heart shape at both sides of the star. I want the heart shape on one side and the triangle on the other. I tried to test it out with just simple terminal print instead of drawing the shapes and it seemed to work.
This is what the output looks like.
I'm not sure how this is as inside the while loop I'm only calling for the shape to generate once.
You must select the random objects before the while correct
loop, but not in the loop. The loop is run in each frame, if you select new random objects in each frame, they will be drawn on top each other.
if i == 0:
g = random.choice([1,2])
if g == 1:
j = 2
elif g == 2:
j = 1
if i == 1:
g = random.choice([0,2])
if g == 0:
j = 2
elif g == 2:
j = 0
if i == 2:
g = random.choice([0,1])
if g == 0:
j = 1
elif g == 1:
j = 0
# Loops while button isn't correct
while correct == False:
# [...]